feat(cell_metrics): source RT-switching junction violins from the cell summary - #41
Merged
Merged
Conversation
…l summary
Move the two RT-switching-by-splice-junction-type violins (all junctions and
unique junctions) out of the report's junctions x classification
explosion and into cell-summary columns computed once during metrics.
This removes the last per-cell junction re-derivation from the report.
Adds 12 per-cell columns in both modes, emitted only when the junctions file
carries the needed inputs, so the report skips a plot exactly when its columns
are absent:
- RTS_{Known,Novel}_{canonical,non_canonical}_junctions: RTS-flagged,
FL-weighted numerators for the all-junction plot. Denominators are the
existing *_junctions totals.
- unique_... and RTS_unique_...: distinct-intron counts for the unique-junction
plot. Isoforms mode collapses the same genomic intron shared across
transcripts via a sparse Jt @ Xp incidence (junction x transcript times
transcript x cell presence), binarized and kept in scipy.sparse so the
(junction, cell) product is never densified. Reads mode dedups introns per
cell with a groupby.
cell_metrics.py also adds RTS_junction and the genomic-coordinate columns to the
otherwise-minimal junctions read (small next to the CB column that dominates the
isoforms junctions file).
SQANTI-sc_report.R gains build_rts_sjtype_long(), which derives each SJ type's
per-cell percentage from the columns (NA when a cell has no junctions of a type,
so it drops out of the violin); both plots are gated on their columns' presence.
Deletes the junc_rt explosion and the now-dead junc_iso_key resolver.
CarlosBlancoGo
added a commit
that referenced
this pull request
Jul 20, 2026
…cating rows (#42) The per-cluster length-distribution violins re-derived their data by exploding the classification CB/FL lists to per-(transcript, cell) rows and then replicating each row FL times (rep(seq_len(n), times = FL)) so every read became a literal row. In isoforms mode the replicated frame is the number of reads -- the same per-read explosion that #35, #36, #40 and #41 removed elsewhere by moving metrics off the report's on-the-fly re-derivation. Aggregate instead to per-(transcript, cluster) with weight = sum(FL), and drive the violin with the native geom_violin weight aesthetic, plus a weighted mean and a weighted five-number box summary computed from a small weighted-quantile helper. This reproduces the FL-replicated distribution exactly at a fraction of the rows: on the test set the weighted mean matches the replicated mean to full precision and the quantiles to within interpolation noise (invisible on the log-length axis); the rendered violins are indistinguishable in both modes. The weighted-quantile helper also handles clusters/category subsets with fewer than two points (a single transcript collapses to a degenerate box) so sparse per-category panels no longer abort the whole length-by-cluster block via the outer tryCatch.
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.
Summary
unique junctions) out of the report's on-the-fly junctions×classification
explosion and into real cell-summary columns, computed once during metrics —
removing the last per-cell junction re-derivation from the report.
file carries the needed inputs (so the report skips a plot exactly when its
columns are absent — same behaviour as the old runtime guards).
Details
cell_metrics.pyRTS_{Known,Novel}_{canonical,non_canonical}_junctions— RTS-flagged,FL-weighted numerators for the all-junction plot; denominators are the
existing
*_junctionstotals.unique_…+RTS_unique_…— distinct-intron counts for the unique-junctionplot. Isoforms mode collapses the same genomic intron shared across
transcripts via a sparse
Jt @ Xpincidence (junction×transcript timestranscript×cell presence), binarized and kept in
scipy.sparseso the(junction, cell) product is never densified. Reads mode dedups introns per
cell with a groupby.
RTS_junction+ genomic-coordinate columns to the otherwise-minimaljunctions read.
SQANTI-sc_report.R— newbuild_rts_sjtype_long()derives each SJ type'sper-cell percentage from the columns (NA when a cell has no junctions of a
type, so it drops out of the violin); both plots are gated on their columns'
presence. Deletes the
junc_rtexplosion and the now-deadjunc_iso_keyresolver.
reads-mode RTS/unique).