This is a test version of Biostars. For the public version, visit https://www.biostars.org.
Dealing with massive CNV hyper-calling in DRAGEN Germline Enrichment: Best post-hoc VCF filtering and cohort collapse strategy?

Hi everyone,

I recently ran a cohort of 90 targeted enrichment samples through the DRAGEN Germline Enrichment CNV Calling pipeline (v4-4-6). I am now looking at the resulting *.cnv.vcf.gz files and I am seeing massive hyper-calling—over 100,000 CNVs across the 90 samples (averaging over 1,100 per sample).

Since I have already completed the computationally expensive DRAGEN runs and have the VCFs, I want to avoid re-running the raw data to tweak baseline/PON settings if possible. I am planning to implement a post-hoc filtering workflow and would love to get feedback on whether this approach is sound or if I'm missing any community best practices.

Here is my current plan to tackle the noise:

  1. Hard Filtering via bcftools: I plan to strip out low-confidence transitions and sequencing artifacts by enforcing PASS and dropping calls flagged with dinucQual (indicating polymerase slippage in repetitive motifs) and cnvBinSupportRatio. I am also considering mandating a minimum Bin Count of 3 (BC >= 3) to ensure the call is supported by multiple independent target intervals rather than a single noisy probe.
  1. Spatial Boundaries: I plan to intersect the VCFs strictly against my capture BED, and then subtract known high-homology blacklists (like ENCODE) to drop recurring mapping artifacts.
  1. Cohort-Level Frequency Filtering: Because a lot of these are likely systematic assay artifacts, my plan is to merge the 90 VCFs with bcftools merge, and then use truvari collapse to consolidate redundant calls. I've seen recommendations to apply a 70% reciprocal overlap and 70% size similarity threshold for collapsing. After collapsing, I would annotate the occurrence count across the cohort and filter out any event appearing in >= 5% of my samples.

My questions for the community:

A. Are there other DRAGEN-specific VCF fields (like QUAL, PE, SM) that you rely on heavily for stripping false positives in exome CNVs?

B. Because target enrichment CNV breakpoints are notoriously "fuzzy" due to unsequenced intronic spaces, are there specific truvari collapse parameters (like --refdist) you recommend tweaking for exome data?

C. Is there a better or more standardized tool for cohort-level CNV artifact suppression without going back to the read counts or BAMs?

Thanks in advance for any insights!

cnv truvari whole-exome bcftools-filtering dragen

1 answer

Hi yawolberg ,

I've attempted to address your question below, but I need to add some context and cautionary notes.

Treat ~1,100 CNVs/sample in targeted enrichment as a QC/normalization/design problem until proven otherwise ~1,100 CNVs/sample in targeted enrichment should be treated as a normalization/QC/design problem until ruled out. Note: DRAGEN docs explicitly caution that self-normalization is not recommended for WES/targeted sequencing because the data may be insufficient; panel-of-normals (PoN) normalization is the intended approach for WES/targeted panels when matched normal samples are available.

Before doing extensive downstream filtering, I would check the VCF headers and DRAGEN CNV metrics for the target BED used, number of normal samples, case-vs-PoN correlation, Coverage MAD, median bin count, and whether self-normalization was used. If the run produced .target.counts.gz or .target.counts.gc-corrected.gz, you may be able to rebuild a better PoN and rerun only the CNV normalization/calling stage from counts rather than rerunning the raw BAM/FASTQ pipeline.

------ Now then ------

For VCF-only triage, I would start with PASS only, but note that PASS already removes records carrying filters such as dinucQual, cnvQual, cnvCopyRatio, cnvLikelihoodRatio, etc. Dropping named filters separately only matters if you plan to rescue some non-PASS calls. For Germline WES/enrichment, I would pay attention to QUAL, SM, CN, BC, and especially WES-specific LR/cnvLikelihoodRatio. I would be cautious with universal thresholds: SM is a linear copy ratio centered around 1.0, so normal heterozygous deletions and duplications should be interpreted relative to that scale. A hard BC >= 3 filter is reasonable for suppressing single-probe artifacts, but it will remove real single-exon and two-exon CNVs, so it depends on your sensitivity requirements.

For the capture-BED step, I would avoid requiring precise breakpoint containment in the BED. Exome/enrichment CNV breakpoints are usually fuzzy because the introns are not measured. Instead, project each call onto the captured intervals and annotate the number of affected targets/exons/genes. Filter on target-bin support rather than exact genomic breakpoints.

For cohort collapse, bcftools merge plus truvari collapse is reasonable, but make sure symbolic CNV records have unique IDs and consider bcftools merge -m id, because symbolic SV records can otherwise be merged incorrectly. For depth-based exome CNVs, I would start with looser Truvari parameters than typical breakpoint-resolved SVs, for example --pctseq 0, --pctsize 0.5, --pctovl 0.5, and --refdist tuned to the capture design/inter-target spacing. Use --chain cautiously, because it can help with breakpoint drift but can also over-collapse recurrent noisy regions.

For artifact suppression, I would build a cohort recurrence annotation rather than permanently deleting events at first. With 90 samples, a 5% threshold means five samples, which is reasonable for flagging likely recurrent assay artifacts but can also remove common real CNVs. I would annotate events against population SV/CNV resources such as gnomAD SV and gnomAD v4 CNVs, and I would keep a whitelist path for known pathogenic or dosage-sensitive loci.

Hi LauferVA,

Thanks for responding to my query. It was really insightful and I have have gained a lot from it.

So I ran DRAGEN Germline Enrichment v4-4-6, with the target BED file containing the coordinates of the exome capture probes used for hybridisation. The average DOC of the 90 samples used was ~40x, which is quite low but we are trying to make exome sequencing more cost effective.

When I analysed the a cnv_metrics.csv file, I found a Median Bin Count of 0.44, which is quite poor; a Coverage MAD of 0.09928, which means the data was too noisy; and 1,125 Total CNVs.

The target_bed_coverage_metrics.csv file showed that 61.40% of aligned bases were strictly on-target; 58.83x Average Autosomal Coverage; and 94.4% of the the targets had at least 1x coverage.

In the coverage file, I saw this:

PCT of target region with coverage [ 0x: 1x),5.56%

This means there was 5.56% 'dead space' in my capture kit. This could mean the cohort-level normalisation failed to converge and DRAGEN's probabilistic model tried to 'over-correct' for it.

After that run, I had run a separate job with the same 90 samples, this time using a custom target BED file that contained coordinates of regions that had at least 20x coverage at each region in each sample. I used MosDepth to calculate the coverages. Here the Median Bin Count jumped from 0.44 to 1.05 (which seems like a statistically stable baseline). The Average Autosomal Coverage on-target rose to 108.36x and the Uniformity improved:

PCT of target region with coverage [20x: inf),99.08%

There were also significantly fewer CNVs in the sample, with 148 DUPs and 47 DELs. The percentage of passing calls also increased.

Do you think this is a viable strategy?

Also, do you have an idea as to why the SEX would be listed as UNDETERMINED?

Also, do I need to add functional data to confirm the validity of CNVs. I was hoping to use more general exome sequencing-based CNV calling associated factors, such as CNV size, RDratio, number of baits, etc.

Kind regards

Hi again,

I've attempted to address your question below, but as before there are some cautionary notes.

The False-Negative Trap in Custom BED Filtering While using a custom BED file restricted to regions with 20x coverage improves your baseline stability metrics, ultimately I still advise against this strategy because it will introduce a significant false-negative problem. By requiring every region in your BED file to maintain at least 20x coverage across all samples, you are systematically excluding the exact genomic intervals where a single sample has a true biological deletion. If a heterozygous or homozygous deletion exists, the local depth will naturally drop below 20x, causing that region to be masked.

WES structural variant detection fundamentally relies on these localized drops in read depth to flag hemizygous or homozygous deletions. DRAGEN’s structural variant detection utilizes accelerated algorithms and relies on a Shifting Levels Model (using a Viterbi hidden Markov model) to identify ploidy states based on these transitions in coverage. If you remove localized drops from the analysis space, the pipeline becomes mathematically blind to the deletions.

For that reason, the apparent improvement in your Coverage MAD and the jump in Median Bin Count to 1.05 could well be (maybe even probably are) artifacts of survivorship bias—they may reflect a forced mathematical stability resulting from stripping the biological variance from the input data ...

An alternative approach: To handle the 5.56% "dead space" without sacrificing sensitivity, identify only the targets that consistently fail across the entire cohort (e.g., 0x to 1x coverage in 95% of samples) and exclude only those systematically dead probes. For probes with low but consistent coverage, rely on cohort-level normalization (Panel of Normals) to resolve coverage biases. If a probe consistently yields 10x coverage across your cohort due to hybridization thermodynamics, the normalization model will correctly establish 10x as the expected diploid baseline for that locus.

Why SEX is Listed as UNDETERMINED DRAGEN’s Ploidy Estimator infers genetic sex by calculating the ratio of median read coverage on the X and Y chromosomes relative to the median coverage across all autosomes.

In Whole Exome Sequencing, capture kits are frequently sparse over the Y chromosome or heavily biased toward the pseudoautosomal regions (PAR). If the target footprint on the sex chromosomes does not yield enough data, or if the calculated ratios fall outside DRAGEN's strict empirical confidence intervals, the automated sex assignment fails. When this occurs, DRAGEN conservatively defaults to a FEMALE baseline to prevent artifactual, male-specific hemizygous baseline assumptions that would cause massive false-positive duplications across the X chromosome.

If you know the phenotypic sex of your samples, you can bypass the heuristic entirely by explicitly passing --sample-sex as a command line argument.

Confirming CNV Validity Without Functional Data Functional data (such as RNA expression assays) is not strictly required for variant calling or initial triage (plenty of clinical tests do NOT do this), but in practical terms I can tell you it is enormously helpful, and sometimes offers additional insight and is definitive. You can establish a high-confidence research dataset by relying on the probabilistic heuristics generated within DRAGEN's Variant Call Format (VCF) output.

Specifically, you should filter your CNVs using these built-in metrics: BC (Bin Count): The number of discrete genomic intervals comprising the variant. Setting a minimum threshold (e.g., BC >= 3) aggressively screens out small, localized technical artifacts. SM (Linear Copy Ratio of Segment Mean): A value converging near 0.5 strongly signifies a heterozygous deletion, while ~1.5 signifies a single-copy duplication. LR (Log10 Likelihood Ratio): A probabilistic metric comparing the likelihood of the alternative allele hypothesis (a true biological CNV) against the null hypothesis (technical library noise).

Orthogonal validation (such as MLPA or microarrays - or perhaps RNA seq as you describe) remains the standard if you are moving toward clinical classification, but relying on robust target-bin support and coverage ratios is entirely sufficient for most research scenarios.

Log in to answer this question.