Results are not what I expected¶
Fewer sample columns than samples¶
Rows in metadata.csv sharing an RG_Sample are merged into one VCF column and their depths add together. Eight FASTQ pairs with four distinct RG_Sample values give four columns (usually intentional, occasionally not). The pooling is printed at the start of every run, before any compute. Metadata ->
A pool is named after my files, or one sample became two pools¶
RG_Sample is blank, so it was filled from SampleID, and SampleID carries whatever your sequencer put in the file name. Nothing failed: the run completed and the name simply traveled. A08781_S58 is now the VCF column, the frequency table header, and the key every analysis result is filed under, with a sample sheet's row number inside it.
The more expensive version of the same cause is a sample sequenced across two lanes. It arrives as A08781_S58_L001 and A08781_S58_L002, and with RG_Sample blank those are two different pools rather than one: each carries half the depth it should, and the cross-sample filter sees twice as many pools as you have, which changes which alleles survive it.
Step 0 prints the pooling it resolved before any compute is spent, and that line is where to catch this:
If it names your files rather than your samples, fill in RG_Sample and rerun. Doing that changes the pooling, so the run will ask you to clear the outputs produced under the old one, which is correct: those numbers really were computed over the wrong pools. Sequencer suffixes ->
Sample columns in an unexpected order¶
Column order follows metadata.csv row order. Where rows share an RG_Sample, the merged column takes the position of the first of them. Metadata →
REF does not match my reference genome¶
Correct. Step 7 re-encodes each site so the most-read allele across the whole cohort becomes REF, which is what makes frequencies comparable across samples and runs. If you need the assembly's base, take it from the assembly. Why →
A variant I know is real is missing¶
Work outward through the chain. A read lost at alignment cannot be recovered later.
| Check | Parameter |
|---|---|
| Was it filtered at alignment? | cleanBAM.mapq (30 is strict), cleanBAM.filter |
| Was the depth truncated? | That sample's Output/Reports/Depth/ report, then variantCall.maxDepth |
| Was it seen in too few pools? | filterFalsePositives.sampleThreshold: the default discards alleles found in one pool out of eight |
| Below the frequency floor? | poolSize, ploidy |
| Site removed on quality? | vcffilter.minQUAL |
Much less depth than I sequenced for¶
Two usual causes, in order of likelihood:
- MAPQ filtering. At
cleanBAM.mapq = 30, repetitive genomes lose a lot. Compare read counts inOutput/Aligned/andOutput/Ready/. - Duplicate removal. The step 4 log carries
markdup -sstatistics; a high duplicate rate is a library-prep problem, not a pipeline one.
Depth plateaus at one number¶
Something capped it, and the depth report says what. grep -H 'ceiling applied' Output/Reports/Depth/*_depth_report.txt.
If the plateau is in one sample at an unround number, that is its measured ceiling and it is working as intended. The report gives the reason, and param_capMaxDepth overrules it for that sample. If every sample plateaus at the same number, the cap is flat rather than measured: either capBAM.maxDepth is set to a fixed depth, or variantCall.maxDepth is non-zero. Depth capping ->
The run stopped saying nothing survived a filter¶
A run that would have produced an empty result is stopped rather than allowed to publish one. There are three of these, each naming the setting responsible, and each stops before anything is written - so no results directory is left holding an empty table for a later run to skip past.
| What it says | What emptied it | What to look at |
|---|---|---|
variant calling produced no records at all |
the pileup reached bcftools call with nothing in it |
variantCall.scaleMapQ against variantCall.varQualMin - below the minimum discards every read |
no site survived the cross-sample filter |
every allele was seen in too few pools | filterFalsePositives.sampleThreshold, poolSize |
no site survived the depth and quality filter |
every site had a sample under the floor, or too low a QUAL; with keepLowDepthAsZero, fewer than minSamples cells at the floor |
vcffilter.minDP, vcffilter.minQUAL, vcffilter.keepLowDepthAsZero, vcffilter.minSamples |
Why this is a refusal and not a warning. Every stage downstream succeeds over no records: bcftools writes a well-formed header with no rows, vcftools --recode exits 0, and the conversion rewrites the header and never enters its body. Before these checks existed, the result of a run that found nothing was a frequency table holding column names and nothing else, from a run that reported success. Measured through all seven stages.
The depth and quality filter is the most common of the three, and it catches people out because it is applied to the whole site: one sample below minDP removes that site for every sample, so the shallowest library sets the threshold for the entire cohort, unless vcffilter.keepLowDepthAsZero is on. Check Output/Reports/Coverage/ for your weakest sample before raising it.
Genotype-based tools find nothing in my VCFs¶
FORMAT/GT is set to ./. throughout, deliberately: a pool has no genotype, and leaving bcftools' diploid call in place would invite tools to read it as one. Use AD and DP.
Annotated VCF contains sites missing from my frequency tables¶
Step 8 runs on step 6's output, in parallel with the frequency branch, so it never sees the step 7 filters. Its allele encoding is also the original reference-based one, not the major-allele normalized one. Join on CHROM/POS and expect unmatched rows. Details →