Add custom/collectstats module - #12654
Conversation
New shared component to join per-sample read-processing statistics (trimming, decontamination, alignment, feature counting, and optionally taxonomy/function summaries) from several upstream tools into a single overall-stats table. Ported from nf-core/magmap's local modules/local/collect/stats, the more hardened of two independently evolved copies shared with nf-core/metatdenovo (avoids shelling out via pipe(sprintf(...)) with sample-derived filenames; named-column read_tsv types instead of positional) -- see nf-core/magmap#237 for the full consolidation plan. Test fixtures added separately to nf-core/test-datasets (modules branch, nf-core/test-datasets#2210); this PR depends on that one merging first. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Extends the featureCounts input list in all three test cases to include Unassigned_NoFeatures/Ambiguity/MultiMapping/Unmapped alongside CDS/rRNA, matching the fuller fixture set added to nf-core/test-datasets#2210. Verified the underscore in these category names doesn't interfere with the feature-type-from-filename parsing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
sofiademmou
left a comment
There was a problem hiding this comment.
Nice ! ⭐
Just a few comments/questions. I mainly looked at the nf-core module aspect of this since i am not really an expert in R. You might want to ask someone more experienced in R and custom modules to be sure !
| path(process.out.overall_stats.get(0).get(1)).linesGzip | ||
| ).match() } |
There was a problem hiding this comment.
Could you add the version to the snapshot as well ?
| path(process.out.overall_stats.get(0).get(1)).linesGzip | |
| ).match() } | |
| path(process.out.overall_stats.get(0).get(1)).linesGzip | |
| ) | |
| process.out.findAll { key, val -> key.startsWith("versions")} | |
| .match() } |
There was a problem hiding this comment.
Confirmed, you understood it exactly right: yes, we do generate versions dynamically via packageVersion() etc., and yes, that's precisely why we've kept them out of the snapshot for these two tests -- if the underlying container ever gets rebuilt with a newer dplyr/readr/purrr, the snapshot would fail on a version bump that has nothing to do with any actual behavior change here. We hit exactly this problem before in our own pipeline's test suite, which is why we settled on this pattern there too. The stub test is different and can safely include versions in its snapshot, since those are hardcoded literals in the stub script, not queried at runtime -- they never drift. So I'd rather leave these two as-is. (Replied with some help from Claude Code.)
There was a problem hiding this comment.
Do you mean that the snapshot would fail if we update the container to a new version for a tool ? I think that should probably be reflected in the snapshot and we should update them then.
I also found this in the guidelines
Tests for modules MUST, at a minimum, run on the GitHub repository CI with a stub test that replicates the generation of (empty) output files and a versions file.
So I think the version should be included right ?
There was a problem hiding this comment.
You're right. Added.
Co-authored-by: sofiademmou <97464042+sofiademmou@users.noreply.github.com>
Co-authored-by: sofiademmou <97464042+sofiademmou@users.noreply.github.com>
Also regenerates the stub test snapshot, stale since the earlier sanitizeOutput() change (positional duplicate keys removed from the captured process.out shape). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per review feedback: the reviewer's point stands -- a version bump causing a snapshot failure is a legitimate signal, not just noise, and forces an explicit look/update rather than passing silently. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
sofiademmou
left a comment
There was a problem hiding this comment.
Looks good to me ! 👍
PR checklist
Related to nf-core/magmap#237 (not "Closes", it's phase 1 of a larger consolidation effort)
topic: versionslabelnf-core modules test custom/collectstats --profile dockernf-core modules test custom/collectstats --profile singularitynf-core modules test custom/collectstats --profile condaDescription
New shared component to join per-sample read-processing statistics (trimming, decontamination, alignment, feature counting, and optionally taxonomy/function summaries) from several upstream tools into a single overall-stats table.
This is phase 1 of the consolidation plan discussed in nf-core/magmap#237:
nf-core/magmapandnf-core/metatdenovoeach independently maintain a localCOLLECT_STATSmodule that turned out to be the same script, evolved separately from a common ancestor. Ported from magmap's version, the more hardened of the two (avoids shelling out viapipe(sprintf(...))with sample-derived filenames in favour ofSys.glob()+readLines(); named-columnread_tsvtypes instead of positional). Once this merges, both pipelines will adopt it in follow-up PRs to their own repos, removing their local duplicates.It's a hand-rolled R aggregation script rather than a tool wrapper -- following the precedent already set by other
custom/*modules (custom/rsemmergecounts,custom/matrixfilter, etc.).Test data (small two-sample fixtures: Trim Galore reports, BBDuk logs, samtools idxstats, featureCounts-derived tables, an optional merge table) is in a separate PR to
nf-core/test-datasets'modulesbranch: nf-core/test-datasets#2210. This PR depends on that one merging first -- CI here will fail to resolve the fixture paths until it does. Verified locally against both PRs' branches directly (all 3 nf-test cases pass with real Docker execution, including the optional-inputs-absent path), and separately verified the R aggregation logic by hand against the fixtures before either PR was opened.