Repository navigation
feat(retag)!: add pair op to build a paired UMI from own/mate tags - #985
Conversation
Shared NanoSeq CRAMs carry each read's barcode in `rb` and its mate's in `mb` rather than a paired `RX`, so they could not be grouped without converting back to FASTQ and re-running extraction and alignment. `OWN,MATE::pair::DST` joins the two string tags into the R1-first paired UMI: `OWN-MATE` on every record except the second read of a pair (paired, not first-of-pair, the same rule `group` uses to pick R1), which gets `MATE-OWN`. Both mates therefore carry the value `fgumi extract` would have written, which `group --strategy paired` and duplex consensus rely on. Sources are kept (compose with `SRC::delete`); a record missing either source skips the op; a non-string source is an error. Only `pair` accepts a comma-separated source list. Also adds a NanoSeq guide section for starting from shared CRAMs. Closes #984 BREAKING CHANGE: `RetagOp` gains a `Pair` variant, and its public `src()` accessor is replaced by a crate-private `sources()`.
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: fulcrumgenomics/fgumi/.coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (6)
Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 2 reviews per hour. WalkthroughThe retag command now accepts paired source tags, joins their string values into a destination tag, and propagates invalid-value errors. The NanoSeq guide documents using this operation to build RX tags from shared CRAMs before grouping and duplex consensus calling. ChangesPaired-tag retagging
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant RetagPipeline
participant ApplyOp
participant PairTags
RetagPipeline->>ApplyOp: apply operation to record
ApplyOp->>PairTags: pair source tag values
PairTags->>PairTags: write joined destination tag or report missing source
PairTags-->>ApplyOp: return result
ApplyOp-->>RetagPipeline: return success or error
Merge Risk: ⚪ Minimal · up to The documented NanoSeq workflow retains duplicate-marked reads for family consensus. No actionable merge-blocking risk remains after normal checks. 🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #985 +/- ##
==========================================
- Coverage 96.19% 96.15% -0.04%
==========================================
Files 294 294
Lines 148023 148109 +86
==========================================
+ Hits 142388 142412 +24
- Misses 5635 5697 +62 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
@coderabbitai pause |
|
@coderabbitai review |
✅ Action performedReviews paused. |
✅ Action performedReview finished.
|
Closes #984.
Motivation
Published NanoSeq data (e.g. from the Sanger pipeline) is often shared only as aligned CRAMs. In those files the inline barcode is already trimmed off each read and carried in per-read tags:
rb(this read's barcode) andmb(its mate's), instead of a pairedRX. There was no fgumi tool to turn that into theRXthatgroup --strategy pairedneeds, so users had to convert back to FASTQ and re-run extraction and alignment.What this adds
A
pairoperation forfgumi retag:OWN,MATE::pair::DSTjoins the two string tags into the R1-first paired UMI:OWN-MATEon every record except the second read of a pair (paired and not first-of-pair, the same rulegroupuses to pick a template's R1), which getsMATE-OWN. Both mates of a template therefore carry the identical value thatfgumi extractwould have written. This matters beyondgroup: duplex consensus builds its consensusRXfrom every source read and reverses by segment, so mates must agree.Semantics:
SRC::deleteto drop them.src_missing); no partial join is ever written.Z) tag is an error that stops the run.DSTmust differ from both. Onlypairaccepts a comma-separated source list.-, matching whatgroupsplits on.The NanoSeq guide gains a "Starting from Shared NanoSeq CRAMs" section:
samtools view -b→retag→sort --order template-coordinate→group --strategy paired --edits 0→duplex, with a note that the input must be the full (duplicate-marked, not deduplicated) CRAM and carryMC.Design notes
copy/movetake a source list: a fixed-order concat would give R2 the swapped UMI, and overloadingcopywould give it two different semantics depending on source count.0x80without0x1) followgroup's R1 rule, sopairandgroupalways agree on which read is R1.Breaking change
RetagOp(public infgumi_lib) gains aPairvariant, and its publicsrc()accessor is replaced by a crate-privatesources(). No in-tree callers outside retag are affected.Known limitation
If a run fails on a non-string
pairsource, the output written up to that point is left on disk and is incomplete. This is the pipeline engine's general behavior on a mid-run step failure (not specific to retag), and is documented inretag --help.Testing
pair, a message-level check for every malformedpair/ source-list input, R1/R2/fragment/secondary/supplementary and degenerate-flag ordering, missing sources,DSToverwrite, non-string sources (including a non-stringownwith a missingmate), and the zero-match warning wording.RX:Z:GTT-CTAon both mates at 1 and 2 threads, with the metrics row checked; a non-string source fails the run at both thread counts.cargo ci-fmt,ci-lint,ci-tag-literals, andci-test(10,475 passed) all pass locally.Risk:
retagoutput changes by adding pairedRXtags; ordering is pinned by unit and integration tests. Unsafe code: none added or changed;CLAUDE.mdneeds no allowlist update. Memory bounds, queue capacity, and thread/backpressure policy: none changed.OWN,MATE::pair::DSTtofgumi retag. It joins string tags in R1-first order, reverses their order on paired second reads, skips records with a missing source, and errors if a present source is not a string. Sources remain unless separately deleted.rbandmbtags. The guide specifies retaining the full duplicate-marked CRAM and requiringMCtags.RetagOp::Pair; replace the publicsrc()accessor with crate-privatesources().