Repository navigation
Replace snpfilter.sh with a pysam-based snpfilter.py - #1184
Merged
Merged
Conversation
scripts/snpfilter.sh called samtools mpileup --VCF, an output mode that samtools removed in 1.10, and it never called genotypes, so its output gave CNVkit no heterozygous SNPs. Its pre-filter also discarded every record of a sites-only VCF, the input that doc/baf.rst recommends. The replacement, installed as the console script snpfilter.py, genotypes a sample at known SNP sites with the bcftools bundled in pysam: mpileup with per-sample AD and DP and a depth cap of 8000 reads rather than bcftools' default of 250, then call -m. It needs no external binary, so it also runs in the Docker image, which never had samtools or bcftools. A matched normal BAM, if given, is genotyped jointly, and a PEDIGREE header pairs the two samples for CNVkit. Sites on chromosomes missing from the BAM or the FASTA are skipped, an input error stops the run before the output file is opened, and an output file that is also an input is refused. doc/baf.rst documents this route beside the Mutect2 germline options, including why tumor-only genotyping loses LOH and strongly imbalanced sites, and how --zygosity-freq helps. Fixes #656. Refs #364.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1184 +/- ##
==========================================
+ Coverage 76.76% 77.07% +0.30%
==========================================
Files 75 76 +1
Lines 8491 8597 +106
Branches 1503 1525 +22
==========================================
+ Hits 6518 6626 +108
+ Misses 1543 1540 -3
- Partials 430 431 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
scripts/snpfilter.shcould not produce a VCF that CNVkit can use for BAF analysis. It calledsamtools mpileup --VCF, an output mode that samtools deprecated in 1.9 and removed in 1.10, and the pileup step never called genotypes in any case. Its pre-filter (bcftools view --exclude-uncalled --genotype ^miss) also discarded every record of a sites-only VCF, such as dbSNP or 1000 Genomes common SNPs, which is the inputdoc/baf.rstrecommends for tumor-only samples. The Docker image copied the script onto the PATH, but its conda environment never contained samtools or bcftools, so the script could not run there either.This replaces it with
snpfilter.py, a console script incnvlib/cli/registered in[project.scripts], which resolves the long-standing TODO inpyproject.tomlabout whether the helper could be installed.Behavior
bcftools mpileup -f REF -R SITES -a FORMAT/AD,FORMAT/DP --max-depth 8000 --skip-indels --count-orphans --ignore-RG, thenbcftools call -m.FORMAT/DPis requested explicitly. bcftools 1.21 emitsFORMAT/ADby default but notFORMAT/DP, and without per-sample depth the reader falls back to other fields.call -mruns without--variants-only. Sites where no sample carries an ALT allele are written withALT=., which the CNVkit reader ignores.-A/-C alleleswere evaluated and not used:-Aalone invents spurious ALT alleles under sequencing error, and-A -C alleleschanged no heterozygous call on test data.-n), both BAMs are genotyped jointly and a##PEDIGREE=<Derived=tumor,Original=normal>header is written. Without such a header, CNVkit analyzes the first sample of a two-sample VCF unpaired and never consults the normal's genotype.--ignore-RGis required because two BAMs with the same@RG SMtag are otherwise merged into one sample column. Two BAMs that would get the same name are refused.-oor stdout throughtabio.safe_write. All input checks and the first block run before the output file is opened, so an input error writes nothing. An-opath that is the same file as any input is refused, because the inputs are still being read while the output is written.Interface change
The old command was
snpfilter.sh bam vcf [fasta]and always wrotecalls.vcfin the working directory. The new command requires-f, because bcftools mpileup does not run without a reference, and writes to-oor stdout. The namesnpfilteris kept so that users who know it from #656 and the Docker documentation can find the replacement.Behavior worth knowing
0/1at 70 reads but1/1at 256 or more reads.load_het_snpsthen excludes it, although allelic imbalance is the signal BAF analysis measures. Sites with complete LOH are excluded in tumor-only mode at any depth.--zygosity-freq 0.1recovers the imbalanced sites by classifying on allele frequency, and a matched normal avoids the problem, because heterozygous sites are then selected by the normal's genotype.doc/baf.rstdocuments both.Other changes
Dockerfile: theCOPY scripts/snpfilter.shline is removed. pip installs the console script.doc/baf.rst: new subsection "Genotyping known SNP sites withsnpfilter.py" under "Preparing a VCF", beside the Mutect2--genotype-germline-sitesroute.doc/scripts.rstanddoc/docker.rstare updated to match.Tests
test/test_snpfilter.pybuilds a synthetic genome at test time with pysam: two contigs, 68 SNP sites, and tumor and normal BAMs at 300 reads per site with exact allele counts. It covers:cmdutil.load_het_snpsin tumor-only and paired modes (heterozygous set, finitealt_freq, median near 0.5, LOH sites recovered only with the normal,--zygosity-freqrecovery);@RG SMtag;Each of the following edits to the implementation makes at least one test fail: dropping the PEDIGREE header, the duplicate collapsing, the BAM or FASTA contig filter,
FORMAT/DP, the sample renaming,--ignore-RG,--max-depth, the name-collision check or the same-file check; adding--variants-only; or opening the output before validation.No existing output format or numerical path changes. The full suite passes.
Fixes #656.
Refs #364.