Pass --skip-dup-check to RustQC when --with_umi is set - #1882
Pass --skip-dup-check to RustQC when --with_umi is set#1882FelixKrueger wants to merge 1 commit into
Conversation
UMI deduplication (UMICollapse / UMI-tools) physically removes PCR duplicates, so the BAM has no reads flagged 0x400. RustQC's duplicate-marking preflight check then aborts --use_rustqc --with_umi runs. Duplication QC is not applicable to a deduplicated BAM, so pass --skip-dup-check in the UMI path. The --use_rustqc + --skip_markduplicates combination remains blocked in validateInputParameters() (there duplicates are present-but-unmarked, so bypassing would be incorrect). Closes nf-core#1881
098e1da to
a42220f
Compare
|
Quick update, plus a direction question before I finalise this. I've confirmed on a real Before I invest in generating the nf-test snapshot for the new
Happy to finish either — just let me know which you'd prefer. If Option B, I'll generate and commit the snapshot and mark this ready for review. One thing the snapshot run will formally confirm: RustQC's |
|
Go with Option B, and I don't think it needs any RustQC or module changes. I tested it. Ran RustQC 0.2.1 directly on an unmarked BAM (same zero- More importantly, this just restores parity with the legacy path. The One thing your snapshot run will show: on small/degenerate data RustQC's model fitter can skip a few outputs ( Happy for you to finish B: generate the snapshot, swap the |
| biotype_attr ? "--biotype-attribute ${biotype_attr}" : '', | ||
| '--preseq-seed 1 --preseq-seg-len 100000000', | ||
| '--tin-seed 1 --junction-saturation-seed 1', | ||
| // UMI dedup (UMICollapse / UMI-tools) physically removes PCR duplicates, so the |
There was a problem hiding this comment.
Trim AI narrative as well please
Pass
--skip-dup-checkto RustQC when--with_umiis setCloses #1881.
Why
RustQC reads the duplicate flag (
0x400); it does not mark duplicates itself. In the UMI path, UMI-based deduplication (UMICollapse / UMI-tools) physically removes PCR duplicates, and the workflow skips Picard MarkDuplicates whenever--with_umiis set (workflows/rnaseq/main.nf):So
--use_rustqc --with_umihands RustQC a BAM with zero flagged reads, and RustQC aborts:PR #1869 added a validation error for
--use_rustqc+--skip_markduplicates, but the UMI path is not covered by that check (skip_markduplicatesstaysfalse), so it still fails at the RUSTQC step.What
Add
--skip-dup-checkto RustQC's args only whenparams.with_umiis set (conf/modules/rustqc.config). On a UMI-deduplicated BAM, duplication-based QC is not applicable — the duplicates the metric measures were intentionally removed upstream — so bypassing the check produces the correct (degenerate) result while all other RustQC metrics (RSeQC, Preseq, Qualimap, featureCounts biotype, SAMtools) are computed normally.Why not also
--skip_markduplicates?Deliberately scoped to
with_umionly. The--use_rustqc+--skip_markduplicatescase is a genuinely different situation and is already blocked invalidateInputParameters()(#1869): there the duplicates are physically present but unmarked, so bypassing the check would make RustQC report incorrect (near-zero) duplication metrics. In the UMI case the duplicates are gone, so a zeroed/skipped dup metric is correct. This PR leaves the #1869 validation untouched.Alternative considered
Extending the #1869 validation to also block
--use_rustqc --with_umi(erroring out, consistent with the--skip_markduplicatesdecision). That is simpler and lower-risk, but it removes RustQC support for UMI runs entirely, forcing them onto the slower legacy QC path. This PR takes the functionality-preserving route instead; happy to switch to the block-and-error approach if maintainers prefer.Changes
conf/modules/rustqc.config— appendparams.with_umi ? '--skip-dup-check' : ''to the RUSTQCext.argslist.tests/rustqc.nf.test— add ause_rustqc --with_umipipeline test (mirrors the UMI params fromtests/umi.nf.test).CHANGELOG.md— changelog entry.Testing notes / to confirm in CI
nf-test test tests/rustqc.nf.test --profile docker --update-snapshot(andtests/rustqc.nf.test.snapcommitted).dupradaroutput is declared non-optional in the module (emit: dupradar path("${prefix}/dupradar/*")). This PR assumes--skip-dup-checkbypasses only the preflight check and RustQC still emits dupradar files (degenerate on a deduplicated BAM). If instead it emits nothing under--skip-dup-check, thedupradaroutput would needoptional: true— the new test will surface this.#XXXXPR-number placeholder in the CHANGELOG line should be replaced once the PR is opened.