VarScan expects a ‘normal’ and a ‘tumor’ sample pair as its input and detects somatic mutations in the tumor sample that are not present in the normal one using Fisher’s exact test. As in our dataset, two sample pairs with identical DNA sequences were available, we used one sample from a pair as the ‘tumor’ and the other one as the ‘normal’ sample (and vice versa). This way, all detected mutations are false positives as these pairs were created by sequencing the same DNA preparation twice.
VarScan 2 was run based on the best practices described here :
In a later step, results were further filtered by tuning the somatic-p-value parameter.
1. Run SAMtools mpileup on the BAM files for normal and tumor samples:
samtools mpileup –B –q 1 –f reference.fasta normal.bam tumor.bam >normal-tumor.mpileup
2. Run VarScan in somatic mode, providing the mpileup file (normal-tumor.mpileup) and a basename for output files (output.basename):
java –jar VarScan.jar somatic normal-tumor.mpileup
output.basename –min-coverage 10 –min-var-freq 0.08 –somatic-
p-value 0.05
The above recommended values of VarScan parameters were used throughout the run below. The above command will generate two output files, one for SNVs (output.basename.snp) and one for indels (output.basename.indel).
3. Run the processSomatic subcommand to divide the output into separate files based on somatic status and confidence:
java –jar VarScan.jar processSomatic output.basename.snp
java –jar VarScan.jar processSomatic output.basename.indel
This command will generate six files per input file. For SNVs, the output files will be:
- output.basename.snp.Somatic – all somatic mutations
- output.basename.snp.Somatic.hc – high-confidence somatic mutations
- output.basename.snp.LOH – all LOH events
- output.basename.snp.LOH.hc – high-confidence LOH events
- output.basename.snp.Germline – all germline variants
- output.basename.snp.Germline.hc – high-confidence germline variants
The subset of high-confidence variants is determined using a few empirically-derived criteria. For example, high-confidence somatic mutations have tumor VAF>15%, normal VAF<5%, and a somatic p-value of <0.03. These are user-adjustable.
4. Run an additional filter on the somatic mutations
java –jar VarScan.jar somaticFilter
output.basename.snp.Somatic.hc –indel-file
output.basename.indel –output-file
output.basename.snp.Somatic.hc.filter
The above command identifies and removes somatic mutations that are likely false positives due to alignment problems near indels. After this step, candidate somatic mutations should also be filtered to remove other artifacts, as described in Support Protocol 1.
Run the False Positive Filter:
+1. Obtain metrics for the list of variants:
bam-readcount –q 1 –b 20 –f reference.fasta –l
varScan.variants BAM_FILE >varScan.variants.readcounts
+2. Run the FPfilter accessory script:
perl fpfilter.pl varScan.variants varScan.variants.readcounts
–output-basename varScan.variants.filter
The above command would create two output files. Variants passing the filter are found in varScan.variants.filter.pass while variants that fail are printed to varScan.variants.filter.fail along with the reason for the failure. Filtering parameters in the fpfilter.pl script are set to recommended values for Illumina paired-end (2×100 bp) reads, but can be modified by the user in the script if desired.
#load modules
import os
import subprocess
import time
#go to working directory
work_dir='/nagyvinyok/adat84/sotejedlik/ribli/dt40/method/varscan_best_practice'
subprocess.call(['mkdir',work_dir])
os.chdir(work_dir)
#gallus reference
galref="/home/ribli/input/index/gallus/complete/Gallus_gallus.Galgal4.74.dna.toplevel.fa"
input_dir='/nagyvinyok/adat84/sotejedlik/ribli/dt40/ident_bams/'
output_dir=work_dir
def run_samt_mp_varscan_som(tum_sample,norm_sample,input_dir,output_dir,ref_genome):
#input files
norm_bam=input_dir+norm_sample+'.bam'
tum_bam=input_dir+tum_sample+'.bam'
#create pileup commands
cmd_mpileup=' <(samtools mpileup -B -q 1 -f '+ ref_genome + ' ' + norm_bam+')'
cmd_mpileup+=' <(samtools mpileup -B -q 1 -f '+ ref_genome + ' '+ tum_bam +')'
#varscan params
pval=' 0.9 '
#output file
output=output_dir+'/'+tum_sample+'_'+norm_sample+'.vsc'
#varscan command
cmd='time java -jar VarScan.v2.3.7.jar somatic '+ cmd_mpileup + ' '+ output
cmd+=' --min-coverage 10 --min-var-freq 0.08 --somatic-p-value 0.05 '
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','10000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
pairs={'S12': 'S15','S27':'S30'}
for tum,norm in pairs.iteritems():
run_samt_mp_varscan_som(tum,norm,input_dir,output_dir,ref_genome=galref)
run_samt_mp_varscan_som(norm,tum,input_dir,output_dir,ref_genome=galref)
def run_varscan_procsom(tum_sample,norm_sample,output_dir,ref_genome):
#output file
input_base=output_dir+'/'+tum_sample+'_'+norm_sample+'.vsc'
#snp
#varscan command
cmd='time java -jar VarScan.v2.3.7.jar processSomatic '+ input_base +'.snp'
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'_ps_snp.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','10000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
#indel
#varscan command
cmd='time java -jar VarScan.v2.3.7.jar processSomatic '+ input_base +'.indel'
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'_ps_indel.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','10000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
for tum,norm in pairs.iteritems():
run_varscan_procsom(tum,norm,output_dir,ref_genome=galref)
run_varscan_procsom(norm,tum,output_dir,ref_genome=galref)
def run_varscan_somfilt(tum_sample,norm_sample,output_dir,ref_genome):
#output file
input_base=tum_sample+'_'+norm_sample+'.vsc'
#varscan command
cmd='time java -jar VarScan.v2.3.7.jar somaticFilter '
cmd+=input_base+'.snp.Somatic.hc --indel-file ' + input_base+'.indel'
cmd+=' --output-file ' + input_base+'.snp.Somatic.hc.filter'
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'_somfilt.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','10000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
for tum,norm in pairs.iteritems():
run_varscan_somfilt(tum,norm,output_dir,ref_genome=galref)
run_varscan_somfilt(norm,tum,output_dir,ref_genome=galref)
def create_beds(tum_sample,norm_sample):
variant_file=tum_sample+'_'+norm_sample+'.vsc.snp.Somatic.hc.filter'
cmd='tail -n+2 '+variant_file+' | awk \'{print $1"\t"$2"\t"$2}\' > '
cmd+=variant_file+'.bed'
print subprocess.check_output(cmd,shell=True),
for tum,norm in pairs.iteritems():
create_beds(tum,norm)
create_beds(norm,tum)
def run_bamcount(tum_sample,norm_sample,input_dir,ref_genome):
#output file
variant_file=tum_sample+'_'+norm_sample+'.vsc.snp.Somatic.hc.filter.bed'
bam_file=input_dir+tum_sample+'.bam'
#command
cmd='~/tools/bam-readcount_build/bin/bam-readcount -q 1 -b 20'
cmd+=' -f ' + ref_genome + ' -l ' + variant_file +' '
cmd+= bam_file + ' > ' +variant_file+'.readcounts'
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'_bamcount.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','2000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
for tum,norm in pairs.iteritems():
run_bamcount(tum,norm,input_dir,ref_genome=galref)
run_bamcount(norm,tum,input_dir,ref_genome=galref)
def run_fpfilter(tum_sample,norm_sample):
#output file
variant_file=tum_sample+'_'+norm_sample+'.vsc.snp.Somatic.hc.filter'
#command
cmd='perl ~/tools/VarScan/fpfilter.pl '+ variant_file +' '
cmd+= variant_file+'.bed.readcounts '
cmd+=' -output-basename '+variant_file+'.fpfilter '
print cmd,'\n'
#write scriptfile for sbatch
script_fn=tum_sample+'_'+norm_sample+'_fpfilter.sh'
with open(script_fn,'w') as f:
f.write('#!/bin/bash\n'+cmd+'\n')
#submit script to sbatch
print subprocess.check_output(['sbatch','-C','jimgray84','--mem','2000',script_fn],
stderr=subprocess.STDOUT),'\n\n'
for tum,norm in pairs.iteritems():
run_fpfilter(tum,norm)
run_fpfilter(norm,tum)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
header=pd.read_csv('S27_S30.vsc.snp.Somatic.hc.filter',sep='\t').columns
df_dict=dict()
for tum,norm in pairs.iteritems():
df_dict[tum]=pd.read_csv(tum+'_'+norm+'.vsc.snp.Somatic.hc.filter.fpfilter.pass',
sep='\t',header=None)
df_dict[tum].columns=header
df_dict[norm]=pd.read_csv(norm+'_'+tum+'.vsc.snp.Somatic.hc.filter.fpfilter.pass',
sep='\t',header=None)
df_dict[norm].columns=header
chroms=set(map(str,range(1,28)+[32]) + ['W','Z'])
for key,table in df_dict.iteritems():
df_dict[key]=table[np.array([x in chroms for x in table['chrom']])]
for key,table in df_dict.iteritems():
print key,len(table)
df_dict['S27'].head()
df_dict['S30'].head()
df_dict['S12'].head()
df_dict['S15'].head()
pvals=dict()
for key,table in df_dict.iteritems():
pvals[key]=np.sort(table['somatic_p_value'].values)
fig,ax=plt.subplots()
fig.set_size_inches(12,9)
for key,value in pvals.iteritems():
ax.plot(value,np.arange(len(value)),lw=2,label=key)
ax.axvline(0.05,c='m',linestyle='dotted',lw=5,label='varscan default = 0.05')
ax.axvline(0.008,c='m',linestyle='dashed',lw=5,label='used by Rieber et al. = 0.008')
ax.set_xlabel(r'Somatic p-value threshold',fontsize=16)
ax.set_ylabel(r'False mutations found',fontsize=16)
ax.set_xlim(0.1,5e-5)
ax.set_ylim(0,1500)
ax.set_xscale('log')
ax.grid()
dump=ax.legend(loc='upper right',fancybox='true',fontsize=16)
fig,ax=plt.subplots()
fig.set_size_inches(12,9)
for key,value in pvals.iteritems():
ax.plot(value,np.arange(len(value)),lw=2,label=key)
ax.axvline(0.05,c='m',linestyle='dotted',lw=5,label='varscan default = 0.05')
ax.axvline(0.008,c='m',linestyle='dashed',lw=5,label='used by Rieber et al. = 0.008')
ax.set_xlabel(r'Somatic p-value threshold',fontsize=16)
ax.set_ylabel(r'False mutations found',fontsize=16)
ax.set_xlim(0.1,5e-20)
ax.set_ylim(1,1000)
ax.set_xscale('log')
ax.set_yscale('log')
ax.grid()
dump=ax.legend(loc='upper right',fancybox='true',fontsize=16)
Varscan 2: http://www.ncbi.nlm.nih.gov/pubmed/22300766
best practice: http://www.ncbi.nlm.nih.gov/pmc/articles/PMC4278659/?tool=pmcentrez
Somatic p-value theshold: http://journals.plos.org/plosone/article?id=10.1371/journal.pone.0066621