feat: add geneBody_coverage and read_GC RSeQC tools - #134
Open
BenjaminDEMAILLE wants to merge 1 commit into
Open
feat: add geneBody_coverage and read_GC RSeQC tools#134BenjaminDEMAILLE wants to merge 1 commit into
BenjaminDEMAILLE wants to merge 1 commit into
Conversation
The two RSeQC tools missing from RustQC's coverage: gene body coverage (5'->3' uniformity, the standard RNA degradation / 3'-bias signal) and the read GC distribution (the standard GC-bias check). Both run inside the existing single pass. gene_body_coverage.rs samples 100 percentile positions per transcript with a direct port of RSeQC's mystat.percentile_list, counts coverage at those positions, and flips reverse-strand transcripts so bin 1 is always the 5' end. The port includes Python's round-half-to-even; using f64::round shifts interpolated positions by one base and changes bin counts. Transcripts under 100 bp are skipped, matching RSeQC's --minimum_length default. read_gc.rs bins the GC percentage of each read's query sequence with upstream's filters (skip unmapped, QC-fail and below-MAPQ; keep secondary alignments and duplicates). Rows are sorted by GC percentage rather than emitted in BAM order, which is not reproducible under parallel processing. Reads stored without SEQ are skipped and reported instead of dividing by zero. Both write the RSeQC output files and R scripts, plus native PNG/SVG plots. Toggles: --skip-gene-body-coverage / --skip-read-gc and the matching config sections. Validated against RSeQC 5.05 on tests/data/test.bam: all 100 gene body coverage bins and the full GC table match exactly. Closes seqeralabs#127 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Closes #127.
Adds the two remaining RSeQC tools, both inside the existing single pass.
geneBody_coverage
src/rna/rseqc/gene_body_coverage.rs— 5' → 3' coverage in 100 percentile bins.mystat.percentile_list--minimum_lengthdefault)Nskips do not count as coveredOutputs
{sample}.geneBodyCoverage.txt(RSeQC format),.geneBodyCoverage.r, and a native.curves.png/.svg.One deliberate deviation, documented in the docs and module: RSeQC profiles every entry of a BED12 reference (usually a housekeeping-gene set); RustQC has no BED input here and profiles one representative transcript per gene from the GTF — the one with the most exonic bases, the same choice the TIN analysis already makes.
f64::round(half away from zero), interpolated percentile positions land one base off and 7 of 100 bins came out ±1 against upstream. There's a unit test pinning the rounding behaviour and a note in AGENTS.md.read_GC
src/rna/rseqc/read_gc.rs— GC distribution of mapped reads.ParseBAM.readGC: skip unmapped, QC-fail and below the MAPQ cutoff; secondary alignments and duplicates are counted (upstream does not filter them)Outputs
{sample}.GC.xls,.GC_plot.r, and a native.GC_plot.png/.svg.Two deliberate deviations: rows are sorted ascending by GC percentage (upstream emits Python dict order, which is BAM-order dependent and not reproducible under parallel processing), and reads stored without
SEQare skipped with a warning instead of dividing by zero.Validation against RSeQC 5.05
Ran upstream
geneBody_coverage.pyandread_GC.py(RSeQC 5.05, pysam) ontests/data/test.bam, using a BED12 built fromtests/data/test.gtfwith the same representative-transcript choice:0.00 483)Both references are pinned in new integration tests. Also verified
--threads 4produces byte-identical output to single-threaded, and that the skip flags remove the outputs.Other
rna.gene_body_coverage.enabled,rna.read_gc.enabled(both defaulttrue); CLI--skip-gene-body-coverage,--skip-read-gccargo test— 211 lib + 20 integration tests pass;cargo fmt --check,cargo clippy -- -D warningsclean🤖 Generated with Claude Code