<p>The GATK is probably the most widely used program for this. There are several workflows you can use depending on what types of variants you're interested in (germline or somatic, short variants, copy number, structural). The most common use case is Germline short variant discovery (SNPs and Indels), for which the overall workflow is described here: </p>

<p><a href="https://gatk.broadinstitute.org/hc/en-us/articles/360035535932" rel="noreferrer">https://gatk.broadinstitute.org/hc/en-us/articles/360035535932</a></p>

<p>The GATK team at the Broad Institute now provides workflow scripts written in WDL (Worfklow Description Language) that can be run on pretty much any platform with the Cromwell engine. The workflows include data pre-processing, including mapping (alignment) and some important cleanup operations, plus variant calling and filtering. </p>

<p>One of the advantages of using those workflows is that the Broad uses them in production for all the data they sequence, which nowadays amounts to abut a new human whole genome every five minutes. That means there's a lot of pressure to make sure the tools are reliable and efficient because any interruption of the pipelining operations would be a big problem. They're also highly standardized so that the outputs will be compatible with other datasets and tools. </p>

<p>Disclosure: I work at the Broad Institute and wrote a book about using GATK (<a href="https://oreil.ly/genomics-cloud" rel="noreferrer">https://oreil.ly/genomics-cloud</a>).</p>

CC BY-SA 4.0
2020-04-23T17:17:06.153Z
2020-04-23T17:17:06.153Z
Geraldine_VdAuwera
<h2>1. Adapter Trimming</h2>
<p>One of the first things I do after encountering a set of reads is to remove the adapter sequences from the start and end of reads. Most basecalling software includes some amount of built-in adapter trimming, but it is almost always the case that some adapter sequence will remain. Removing adapters is helpful for mapping because it reduces the effort the mapper needs to go through to make a match (which may help some borderline reads to be mapped properly).</p>
<p>My preferred adapter trimmer is <a href="http://www.usadellab.org/cms/?page=trimmomatic" rel="nofollow noreferrer">Trimmomatic</a>. It has the ability to search for palindromic adapter read through, and includes an adaptive sliding window option. Trimmomatic is threaded, and seems to work reasonably fast when run through files one at a time in threaded mode. Here's an example script that I might run to trim reads from some samples. This puts trimmed FASTQ files into a <code>trimmed</code> subdirectory:</p>
<pre><code>TRIMPATH=/data/all/programs/trimmomatic/Trimmomatic-0.36;
JARPATH=&quot;<span class="math-container">${TRIMPATH}/trimmomatic-0.36.jar";
ADAPTfile="$</span>{TRIMPATH}/adapters/TruSeq3-PE-2.fa&quot;;
CMDS=&quot; ILLUMINACLIP:${ADAPTfile}:2:30:10:5:true LEADING:3 TRAILING:3  SLIDINGWINDOW:10:20 MINLEN:40 &quot;;

mkdir -p trimmed;

for INFILE1 in *_1.fastq.gz; do
  base=<span class="math-container">$(basename "$</span>INFILE1&quot; _1.fastq.gz);
  echo <span class="math-container">${base};
  INFILE2="$</span>{base}_2.fastq.gz&quot;;
  OUTFILE_P1=&quot;trimmed/<span class="math-container">${base}_P1.fastq.gz";
  OUTFILE_P2="trimmed/$</span>{base}_P2.fastq.gz&quot;;
  OUTFILE_U1=&quot;trimmed/<span class="math-container">${base}_U1.fastq.gz";
  OUTFILE_U2="trimmed/$</span>{base}_U2.fastq.gz&quot;;
  java -jar &quot;<span class="math-container">${JARPATH}" PE -threads 20 -phred33 \
        "$</span>{INFILE1}&quot;  &quot;<span class="math-container">${INFILE2}" \
        "$</span>{OUTFILE_P1}&quot; &quot;<span class="math-container">${OUTFILE_U1}" "$</span>{OUTFILE_P2}&quot;  &quot;<span class="math-container">${OUTFILE_U2}" \
        "$</span>{CMDS}&quot;;
done;
</code></pre>
<p>Trimmomatic is somewhat sensitive to bad input data, and will loudly fail (i.e. stop running) if it sees quality strings of different length to sequence strings:</p>
<pre><code>Exception in thread &quot;Thread-1&quot; java.lang.RuntimeException: Sequence and quality length don't match: 'TACATGGCCCTGAAATGACTTTCACCCAGGCAACCAGTGCCCCCTGTATAGACACATGCCTTGGGCGCTCCCCACCCTTCCTCGCGTGGCCACACCTCTGT' vs '-AAFFJFJJ7A-FJJJFJFJFJJFFA-FFAF-&lt;A-&lt;FFFJA-&lt;-A7-F&lt;&lt;FFJJAJJJJJJJJJ--&lt;--7-7AJ7&lt;AAJA--J7&lt;ACTGCTGTGGGGCACCCAGCCCCCCAGATAGCCTGGCAGAAGGATGGGGGCACAGACTTCCCAGCTGCACGGGAGAGAC'
        at org.usadellab.trimmomatic.fastq.FastqRecord.&lt;init&gt;(FastqRecord.java:25)
        at org.usadellab.trimmomatic.fastq.FastqParser.parseOne(FastqParser.java:89)
        at org.usadellab.trimmomatic.fastq.FastqParser.next(FastqParser.java:179)
        at org.usadellab.trimmomatic.threading.ParserWorker.run(ParserWorker.java:42)
        at java.lang.Thread.run(Thread.java:745)
</code></pre>
<h2>2. Read Mapping</h2>
<p>Read mapping finds the most likely location for a read within a target genome.
There are extremely fast approximate mappers available, but these don't yet work for variant calling, and an exact mapping approach is necessary. My current preferred mapper is <a href="https://ccb.jhu.edu/software/hisat2/index.shtml" rel="nofollow noreferrer">HISAT2</a>. I use this instead of BWA due to the double-read issue, and because of the local variant-aware mapping. HISAT2 is made by the same computing group as Bowtie2 and Tophat2 (JHUCCB), and is their recommended tool for replacing those other programs.</p>
<blockquote>
<p>HISAT2 is a successor to both HISAT and TopHat2. We recommend that HISAT and TopHat2 users switch to HISAT2.</p>
</blockquote>
<p>The HISAT2 page includes a link to a <a href="ftp://ftp.ccb.jhu.edu/pub/infphilo/hisat2/data/grch38_snp.tar.gz" rel="nofollow noreferrer">genomic index file</a> for the human genome, including SNP variants, which I use when mapping human reads. HISAT2 is also threaded, so I run it on the files one at a time and pipe through samtools to create a sorted BAM file:</p>
<pre><code>mkdir mapped
for r1 in trimmed/*_P1.fastq.gz;
  do base=<span class="math-container">$(basename "$</span>{x}&quot; _P1.fastq.gz);
  r2=&quot;trimmed/<span class="math-container">${base}_P2.fastq.gz";
  echo $</span>{base};
  hisat2 -p 20 -t -x /data/all/genomes/hsap/hisat_grch38_snp/genome_snp -1 \
    &quot;<span class="math-container">${r1}" -2 "$</span>{r2}&quot; 2&gt;&quot;mapped/hisat2_<span class="math-container">${y}_vs_grch38_stderr.txt" | \
    samtools sort &gt; "mapped/hisat2_$</span>{y}_vs_grch38.bam&quot;;
done
</code></pre>
<h2>3. Variant Calling</h2>
<p>I currently use samtools/bcftools to do this, but would be interested in other opinions as we recently had a grant reviewer response that samtools was a dinosaur program and better approaches were available. Samtools doesn't currently work with threads for variant calling, so I save the commands to a text file and then run them through <a href="https://www.gnu.org/software/parallel/" rel="nofollow noreferrer">GNU Parallel</a>. This requires the genome files to be first downloaded and indexed via <code>samtools faidx</code>. This produces a set of gzipped VCF files in the <code>variants</code> directory:</p>
<pre><code>mkdir -p variants;
(for x in mapped/*.bam;
   do echo samtools mpileup -v -f /data/all/genomes/hsap/hisat_grch38_snp/Homo_sapiens.GRCh38.dna.primary_assembly.fa &quot;<span class="math-container">${x}" \| \
   bcftools call --ploidy GRCh38 -v -m -O z -o variants/$</span>(basename &quot;${x}&quot; .bam).vcf.gz; done) &gt; call_jobs.txt
cat call_jobs.txt | parallel -u;
</code></pre>
<p>As a slow, but more accurate alternative, variants can be called for all samples at the same time:</p>
<pre><code>samtools mpileup -v -f /data/all/genomes/hsap/hisat_grch38_snp/Homo_sapiens.GRCh38.dna.primary_assembly.fa mapped/*.bam | \
  bcftools call --ploidy GRCh38 -v -m -O z -o variants/hisat2_allCalled_vs_grch38.vcf.gz
</code></pre>
<p>If a faster processing is desired, then the variant calling can be parallelised across chromosomes using <code>parallel</code> and merged afterwards using <code>bcftools norm</code>. The implementation of this is left as an exercise to the reader.</p>
<p><em>Aside: I see that <a href="https://software.broadinstitute.org/gatk/best-practices/workflow?id=11145" rel="nofollow noreferrer">GATK's best practise guidelines</a> call per-sample with HaplotypeCaller, then process those VCF files as aggregated data. @Geraldine-vdauwera says this two-step joint calling workflow was designed to be scalable for any size cohort, so you can apply it pretty much the same way whether you have two samples or twenty thousand. Once you go higher than that there are some additional tweaks to keep scaling up.</em></p>

CC BY-SA 4.0
2017-06-12T08:41:12.713Z
2022-06-29T06:02:39.947Z
2022-06-29T06:02:39.947Z
gringer
<p><em>This is a problem I have to solve frequently, and I'd be interested in knowing what other methods people use to solve the same problem.</em></p>

<p>About twice a year, I get asked to determine variants from Illumina reads, usually from either mouse or human. These are things that have good reference genomes (e.g. <a href="http://www.ensembl.org/Homo_sapiens/Info/Index" rel="noreferrer">human genome from ensembl</a>, <a href="http://www.ensembl.org/Mus_musculus/Info/Index" rel="noreferrer">mouse genome from ensembl</a>), and are frequently tested out on various bioinformatics tools.</p>

<p>I have at my disposal three computers, in order of usage preference: a laptop with 4 processing threads and 8GB of memory, a desktop with 12 processing threads and 64GB of memory, and a server with 24 processing threads and 256GB of memory. Occasionally I get access to better computers when I need to do lots of processing, or to do things quickly, but these comprise my basic bioinformatics team.</p>

<p>I've had whole-genome projects that involved processing data from 4 individuals, up to projects with about 120 individuals, with each individual having about 10-40M paired-end reads (100-125bp each). Beyond this level, I suspect other researchers will typically have their own bioinformatics team and/or capabilities, which is why I don't get any of the larger-scale jobs that I hear about from salaried bioinformaticians.</p>

<p>What is the standard approach that you would use to process these reads into reference-mapped variant data (i.e. gzipped VCF) for use in downstream analysis tools (e.g. <a href="http://www.ensembl.org/Homo_sapiens/Info/Index" rel="noreferrer">VEP</a>)?</p>

<variant-calling><read-mapping><human-genome>
How do I generate a variant list (i.e. VCF file) using Illumina reads from a human genome?
# How do I generate a variant list (i.e. VCF file) using Illumina reads from a human genome?

(Asked by: username_0 on 2017-06-12)

*This is a problem I have to solve frequently, and I'd be interested in knowing what other methods people use to solve the same problem.*

About twice a year, I get asked to determine variants from Illumina reads, usually from either mouse or human. These are things that have good reference genomes (e.g. [human genome from ensembl](http://www.ensembl.org/Homo_sapiens/Info/Index), [mouse genome from ensembl](http://www.ensembl.org/Mus_musculus/Info/Index)), and are frequently tested out on various bioinformatics tools.

I have at my disposal three computers, in order of usage preference: a laptop with 4 processing threads and 8GB of memory, a desktop with 12 processing threads and 64GB of memory, and a server with 24 processing threads and 256GB of memory. Occasionally I get access to better computers when I need to do lots of processing, or to do things quickly, but these comprise my basic bioinformatics team.

I've had whole-genome projects that involved processing data from 4 individuals, up to projects with about 120 individuals, with each individual having about 10-40M paired-end reads (100-125bp each). Beyond this level, I suspect other researchers will typically have their own bioinformatics team and/or capabilities, which is why I don't get any of the larger-scale jobs that I hear about from salaried bioinformaticians.

What is the standard approach that you would use to process these reads into reference-mapped variant data (i.e. gzipped VCF) for use in downstream analysis tools (e.g. [VEP](http://www.ensembl.org/Homo_sapiens/Info/Index))?

**Tags:** variant-calling, read-mapping, human-genome

---

## 2 answers

### Answer by username_0 on 2017-06-12. Score: 9 | Accepted answer

1. Adapter Trimming
One of the first things I do after encountering a set of reads is to remove the adapter sequences from the start and end of reads. Most basecalling software includes some amount of built-in adapter trimming, but it is almost always the case that some adapter sequence will remain. Removing adapters is helpful for mapping because it reduces the effort the mapper needs to go through to make a match (which may help some borderline reads to be mapped properly).
My preferred adapter trimmer is Trimmomatic. It has the ability to search for palindromic adapter read through, and includes an adaptive sliding window option. Trimmomatic is threaded, and seems to work reasonably fast when run through files one at a time in threaded mode. Here's an example script that I might run to trim reads from some samples. This puts trimmed FASTQ files into a trimmed subdirectory:
TRIMPATH=/data/all/programs/trimmomatic/Trimmomatic-0.36;
JARPATH="${TRIMPATH}/trimmomatic-0.36.jar";
ADAPTfile="${TRIMPATH}/adapters/TruSeq3-PE-2.fa";
CMDS=" ILLUMINACLIP:${ADAPTfile}:2:30:10:5:true LEADING:3 TRAILING:3  SLIDINGWINDOW:10:20 MINLEN:40 ";

mkdir -p trimmed;

for INFILE1 in *_1.fastq.gz; do
  base=$(basename "$INFILE1" _1.fastq.gz);
  echo ${base};
  INFILE2="${base}_2.fastq.gz";
  OUTFILE_P1="trimmed/${base}_P1.fastq.gz";
  OUTFILE_P2="trimmed/${base}_P2.fastq.gz";
  OUTFILE_U1="trimmed/${base}_U1.fastq.gz";
  OUTFILE_U2="trimmed/${base}_U2.fastq.gz";
  java -jar "${JARPATH}" PE -threads 20 -phred33 \
        "${INFILE1}"  "${INFILE2}" \
        "${OUTFILE_P1}" "${OUTFILE_U1}" "${OUTFILE_P2}"  "${OUTFILE_U2}" \
        "${CMDS}";
done;

Trimmomatic is somewhat sensitive to bad input data, and will loudly fail (i.e. stop running) if it sees quality strings of different length to sequence strings:
Exception in thread "Thread-1" java.lang.RuntimeException: Sequence and quality length don't match: 'TACATGGCCCTGAAATGACTTTCACCCAGGCAACCAGTGCCCCCTGTATAGACACATGCCTTGGGCGCTCCCCACCCTTCCTCGCGTGGCCACACCTCTGT' vs '-AAFFJFJJ7A-FJJJFJFJFJJFFA-FFAF-(FastqRecord.java:25)
        at org.usadellab.trimmomatic.fastq.FastqParser.parseOne(FastqParser.java:89)
        at org.usadellab.trimmomatic.fastq.FastqParser.next(FastqParser.java:179)
        at org.usadellab.trimmomatic.threading.ParserWorker.run(ParserWorker.java:42)
        at java.lang.Thread.run(Thread.java:745)

2. Read Mapping
Read mapping finds the most likely location for a read within a target genome.
There are extremely fast approximate mappers available, but these don't yet work for variant calling, and an exact mapping approach is necessary. My current preferred mapper is HISAT2. I use this instead of BWA due to the double-read issue, and because of the local variant-aware mapping. HISAT2 is made by the same computing group as Bowtie2 and Tophat2 (JHUCCB), and is their recommended tool for replacing those other programs.

HISAT2 is a successor to both HISAT and TopHat2. We recommend that HISAT and TopHat2 users switch to HISAT2.

The HISAT2 page includes a link to a genomic index file for the human genome, including SNP variants, which I use when mapping human reads. HISAT2 is also threaded, so I run it on the files one at a time and pipe through samtools to create a sorted BAM file:
mkdir mapped
for r1 in trimmed/*_P1.fastq.gz;
  do base=$(basename "${x}" _P1.fastq.gz);
  r2="trimmed/${base}_P2.fastq.gz";
  echo ${base};
  hisat2 -p 20 -t -x /data/all/genomes/hsap/hisat_grch38_snp/genome_snp -1 \
    "${r1}" -2 "${r2}" 2>"mapped/hisat2_${y}_vs_grch38_stderr.txt" | \
    samtools sort > "mapped/hisat2_${y}_vs_grch38.bam";
done

3. Variant Calling
I currently use samtools/bcftools to do this, but would be interested in other opinions as we recently had a grant reviewer response that samtools was a dinosaur program and better approaches were available. Samtools doesn't currently work with threads for variant calling, so I save the commands to a text file and then run them through GNU Parallel. This requires the genome files to be first downloaded and indexed via samtools faidx. This produces a set of gzipped VCF files in the variants directory:
mkdir -p variants;
(for x in mapped/*.bam;
   do echo samtools mpileup -v -f /data/all/genomes/hsap/hisat_grch38_snp/Homo_sapiens.GRCh38.dna.primary_assembly.fa "${x}" \| \
   bcftools call --ploidy GRCh38 -v -m -O z -o variants/$(basename "${x}" .bam).vcf.gz; done) > call_jobs.txt
cat call_jobs.txt | parallel -u;

As a slow, but more accurate alternative, variants can be called for all samples at the same time:
samtools mpileup -v -f /data/all/genomes/hsap/hisat_grch38_snp/Homo_sapiens.GRCh38.dna.primary_assembly.fa mapped/*.bam | \
  bcftools call --ploidy GRCh38 -v -m -O z -o variants/hisat2_allCalled_vs_grch38.vcf.gz

If a faster processing is desired, then the variant calling can be parallelised across chromosomes using parallel and merged afterwards using bcftools norm. The implementation of this is left as an exercise to the reader.
Aside: I see that GATK's best practise guidelines call per-sample with HaplotypeCaller, then process those VCF files as aggregated data. @Geraldine-vdauwera says this two-step joint calling workflow was designed to be scalable for any size cohort, so you can apply it pretty much the same way whether you have two samples or twenty thousand. Once you go higher than that there are some additional tweaks to keep scaling up.


---

### Answer by username_1 on 2020-04-23. Score: 6

The GATK is probably the most widely used program for this. There are several workflows you can use depending on what types of variants you're interested in (germline or somatic, short variants, copy number, structural). The most common use case is Germline short variant discovery (SNPs and Indels), for which the overall workflow is described here:

<https://gatk.broadinstitute.org/hc/en-us/articles/360035535932>

The GATK team at the Broad Institute now provides workflow scripts written in WDL (Worfklow Description Language) that can be run on pretty much any platform with the Cromwell engine. The workflows include data pre-processing, including mapping (alignment) and some important cleanup operations, plus variant calling and filtering.

One of the advantages of using those workflows is that the Broad uses them in production for all the data they sequence, which nowadays amounts to abut a new human whole genome every five minutes. That means there's a lot of pressure to make sure the tools are reliable and efficient because any interruption of the pipelining operations would be a big problem. They're also highly standardized so that the outputs will be compatible with other datasets and tools.

Disclosure: I work at the Broad Institute and wrote a book about using GATK (<https://oreil.ly/genomics-cloud>).


---

