RNA and transcripts API¶
See Transcript models for sequence access and RNA imports for observed structures and Exacto predictions.
Mutant transcripts¶
varcode.MutantTranscript(reference_transcript: Optional[object] = None, edits: Tuple[TranscriptEdit, ...] = tuple(), reference_segments: Optional[Tuple[ReferenceSegment, ...]] = None, cdna_sequence: Optional[str] = None, mutant_protein_sequence: Optional[str] = None, annotator_name: str = 'unknown', evidence: Optional[dict] = None)
dataclass
¶
Bases: DataclassSerializable
A reference transcript (or assembled set of reference segments) with zero or more variant-derived edits applied, optionally carrying the mutated cDNA and protein sequences.
Producers (the protein-diff annotator, RNA-evidence importers,
the splice-outcomes rewrite, germline-aware annotation,
structural-variant annotators) construct this once per
(transcript-or-segments, variant-set, context) and hand it to
downstream consumers. Each consumer reads the fields it cares
about — edits for provenance, cdna_sequence /
mutant_protein_sequence for protein-level analysis.
Two shapes:
-
Point-variant shape (
reference_transcriptis set,reference_segmentsisNone) — the mutant is derived from a single reference transcript by applying zero or more :class:TranscriptEditobjects. This is the shape used by the protein-diff annotator for SNVs, MNVs, and simple indels. -
Structural-variant shape (
reference_segmentsis set,reference_transcriptmay beNoneor the primary / 5'-partner transcript) — the mutant is assembled by concatenating :class:ReferenceSegmentslices in order. A gene fusion is two segments from two transcripts; a translocation to intergenic is one transcript segment plus a genomic-interval segment; an inversion is three forward/ reverse/forward segments.editsmay still be populated for point-variant edits layered on top of the assembled segments, but typically an SV carries no extra edits.
Sequence fields are Optional[str] because not every producer
computes them eagerly. Callers that require the protein check or
compute it themselves; the protein-diff annotator guarantees it
for point variants.
Forward-looking hooks (not implemented here; documented so new integrations know where to plug in):
- Personalized / full-genome reference — pass a
:class:
ReferenceSegmentwhosesourceis a patient-specific contig object. varcode's translation logic readssource.sequence; it doesn't care whether that's GRCh38 or a custom assembly. - Long-read resolution — when an SV has an :attr:
alt_assemblyon the :class:StructuralVariant, the SV annotator can wrap that sequence as a single synthetic segment. - SV outcomes ambiguity — a translocation producing many candidate
ORFs that only RNA can resolve should return
List[MutantTranscript]or wrap it in a :class:MultiOutcomeEffectper #299, each with its ownevidencedict capturing the disambiguator.
reference_transcript: Optional[object] = None
class-attribute
instance-attribute
¶
The :class:pyensembl.Transcript this mutant is derived from
(point-variant shape), or the primary / 5'-partner transcript
(SV shape). None when the SV has no canonical primary
transcript (e.g. intergenic-to-intergenic BNDs). Not typed
tightly here so :mod:pyensembl isn't a hard import dependency
for anyone who just wants the dataclass.
edits: Tuple[TranscriptEdit, ...] = field(default_factory=tuple)
class-attribute
instance-attribute
¶
Edits applied to produce this mutant, sorted by
:attr:TranscriptEdit.cdna_start. Empty tuple means the mutant
is identical to the reference (or, for SV shape, the assembled
segments carry the rearrangement directly without further
point-level edits).
reference_segments: Optional[Tuple[ReferenceSegment, ...]] = None
class-attribute
instance-attribute
¶
Ordered tuple of :class:ReferenceSegment objects that, when
concatenated in order (applying reverse-complement to -
strand segments), produce the mutant cDNA. None for the
point-variant shape; a fusion's segments would be
(5p_partner_segment, 3p_partner_segment). Coordinates are
in each segment's own reference system. A partial structural model may
describe only a retained reference fragment: its producer identifies this
in evidence and leaves the full cdna_sequence unknown. Concatenating
those partial segments does not establish a full allele.
cdna_sequence: Optional[str] = None
class-attribute
instance-attribute
¶
The mutated spliced mRNA, when computed. None if the
producer hasn't materialized it yet.
mutant_protein_sequence: Optional[str] = None
class-attribute
instance-attribute
¶
The translated mutant protein, stopping at the first stop
codon. None if not yet translated, or if the edit set
doesn't produce a coherent ORF (e.g. start-codon loss). Callers
that need a guaranteed-present protein should use the
protein-diff annotator once it lands.
annotator_name: str = 'unknown'
class-attribute
instance-attribute
¶
Name of the :class:EffectAnnotator (or other producer) that
created this MutantTranscript. Used as provenance in
serialization and for A/B comparisons.
evidence: Optional[dict] = None
class-attribute
instance-attribute
¶
Optional producer-specific evidence (RNA read counts, Isovar fragment ids, SpliceAI scores, long-read assembly metadata). Shape is annotator-specific and not part of the stable contract; consumers that care about a particular evidence shape should type-check it at the call site.
is_identical_to_reference: bool
property
¶
True if no edits were applied AND there are no
reference-rearranging segments. Does NOT check
cdna_sequence / mutant_protein_sequence — a producer
can legitimately carry an identical sequence with zero edits
and a single identity segment.
is_structural: bool
property
¶
True when this mutant was assembled from
:attr:reference_segments (SV shape) rather than applying
:attr:edits to a single reference transcript.
total_length_delta: int
property
¶
Sum of :attr:TranscriptEdit.length_delta across all
edits — how much longer or shorter the mutant cDNA is than
the reference (point-variant shape). For SV shape, returns
0; the length of an assembled cDNA is the sum of segment
lengths, not a delta against a single reference.
from_sequence(sequence, *, reference_transcript=None, mutant_protein_sequence=None, annotator_name='unknown', evidence=None, label='observed_sequence')
classmethod
¶
Wrap an oriented external sequence without reconstructing it.
Sequence is already in transcript 5'-to-3' order. This constructor
does not infer an ORF, splice structure, or sequence completeness.
Producers must describe partial observations in evidence.
Source code in varcode/mutant_transcript.py
varcode.apply_variant_to_transcript(variant, transcript)
¶
Construct a :class:MutantTranscript by applying variant
to transcript's spliced cDNA.
Returns a :class:MutantTranscript whose cdna_sequence is
populated, plus mutant_protein_sequence when the variant
lies after the start codon (so translation from the canonical
start is well-defined). The codon table is selected from the
transcript's contig — mitochondrial transcripts use NCBI table
2 automatically (see :func:varcode.effects.codon_tables.codon_table_for_transcript).
Returns None when the variant can't be cleanly applied:
- Transcript is not protein-coding or is incomplete.
- Variant doesn't overlap the transcript at all.
- Variant spans more than one exon (splice-junction-crossing variants need the splice-aware path; not handled here).
- Reference allele doesn't match the transcript's cDNA at the computed offset.
Callers that get None should fall back to the fast
:class:EffectAnnotator. The forthcoming protein-diff annotator
layers effect classification on top of this builder.
Source code in varcode/mutant_transcript.py
varcode.apply_variants_to_transcript(variants, transcript)
¶
Apply a list of variants to a single transcript, yielding one
:class:MutantTranscript that carries all the resulting edits
(#269). Used for haplotype-aware joint effect prediction — cis
variants on the same transcript become one combined mutant
rather than N independent per-variant mutants.
Edits are applied in cDNA-coordinate order (highest offset
first, so earlier offsets aren't shifted) to transcript's
spliced cDNA. Returns None when any of the usual
single-variant preconditions fail (non-coding, incomplete, etc.),
or when the provided variants conflict — i.e. claim to edit
overlapping cDNA ranges. The caller is responsible for falling
back to per-variant effects in that case.
mutant_protein_sequence is populated when at least one edit
lands after the canonical CDS start; the joint cDNA is translated
from there to the first stop.
Order of variants doesn't matter — edits are sorted by cDNA
offset internally.
Source code in varcode/mutant_transcript.py
479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 | |
Observed RNA import¶
varcode.load_exacto_fusions(structures_path, integrated_path, *, variants_by_id, cds_starts=None, primary_structures_path=None)
¶
Import selected SV-linked RNA models as an RNAEvidence resolver.
| PARAMETER | DESCRIPTION |
|---|---|
structures_path
|
Exacto transcript-structures and integrated-variants TSVs (optionally
gzip-compressed). Structure
TYPE:
|
integrated_path
|
Exacto transcript-structures and integrated-variants TSVs (optionally
gzip-compressed). Structure
TYPE:
|
variants_by_id
|
Exacto DNA call IDs to existing StructuralVariant objects, normally loaded from VCF. Only these IDs are selected from the integration table. The explicit join avoids inventing a DNA breakpoint from an RNA splice.
TYPE:
|
cds_starts
|
Optional, explicitly chosen zero-based ORF starts in assembled sequence,
keyed by
TYPE:
|
primary_structures_path
|
Optional native Exacto primary-structures TSV (including peptide_id). Import each peptide separately, validate its codons against the observed RNA, and retain partial-protein status and per-base provenance. Cannot be combined with cds_starts. These are sequence predictions, not protein expression evidence. Models without peptide rows remain untranslated.
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
RNAEvidence
|
|
Notes
Supports linear two-locus models with an annotated sense 5' anchor. A missing or antisense 3' partner remains TranslocationToIntergenic, never a guessed coding fusion. Incomplete sequence, unknown transcript IDs, circular paths and multi-gene (>2) models raise rather than silently losing structure. This does not import all Exacto variant types. Exacto's native primary structures use the standard genetic code; that producer choice is recorded. Read/model completeness and read support are not inferred from row counts.
Source code in varcode/exacto.py
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
varcode.make_fusion_outcome(variant, transcript, *, sequence, transcript_model_id, partner_transcript=None, cds_start=None, source='rna', read_count=None, extra_evidence=None)
¶
Import one RNA junction/model using existing structural effect classes.
sequence is the observed 5'-to-3' sequence, never genomic-forward
sequence. transcript is its annotated 5' anchor. Supply a 3' partner
only when the observed path joins that transcript in sense orientation;
otherwise leave it None and retain the locus/orientation in evidence.
An absent partner gives TranslocationToIntergenic, not a coding GeneFusion.
No reference exons are appended and no ORF is guessed. An explicit
zero-based cds_start requests translation of a complete start-to-stop
ORF in the supplied sequence; invalid or incomplete ORFs raise ValueError.
Such a protein is sequence-predicted, not evidence of translation.
Source code in varcode/rna_evidence.py
varcode.RNAEvidence(candidates=())
¶
Imported candidates, also usable as an RNAEvidenceResolver.
Keeps each observed model separately; read counts do not become likelihoods. A fusion is available on both explicitly identified partner transcripts.
Source code in varcode/rna_evidence.py
RNA evidence¶
varcode.RNAEvidenceResolver
¶
Bases: Protocol
Source of RNA-observed outcomes for a (variant, transcript)
pair.
Implementers return zero or more :class:~varcode.effect_candidates.EffectCandidate
objects describing isoforms, fusions, or RNA-level events that were
actually observed in reads. An empty sequence means "no evidence
for this pair" — the existing DNA-predicted outcomes are left
alone.
Returned outcomes should set source to a producer-specific
string (the name of the RNA assembler, long-read caller, fusion
detector, etc.) and populate evidence with whatever shape that
producer natively emits (transcript model IDs, junction read
counts, etc.). See :func:make_rna_outcome for a convenience
factory that fills the common fields.
observed_outcomes(variant, transcript) -> Sequence[EffectCandidate]
¶
Return RNA-observed outcomes for variant on
transcript, or an empty sequence when no evidence is
available. Must not raise on unknown (variant, transcript)
pairs — return an empty sequence instead.
Source code in varcode/rna_evidence.py
varcode.NullRNAEvidenceResolver
¶
No-op resolver that always reports "no evidence".
Useful as a default in pipelines where an RNA resolver is optional
and as a baseline in tests. apply_rna_evidence_to_effects is
safe to call with this resolver — it's a no-op walk.
varcode.apply_rna_evidence_to_effects(effects: Iterable, resolver) -> Iterable
¶
Attach RNA-observed candidates from resolver to each effect.
Walks effects and, for any effect with a resolvable
(variant, transcript), asks resolver.observed_outcomes
for RNA-observed candidates.
Splice mechanism sets use RNA evidence as a reconciliation signal:
a new set replaces the old one, retaining an audit trail of raw RNA
evidence, added candidates, excluded DNA-predicted candidates, and
per-current-candidate RNA support. Other multi-outcome effects keep
the additive side-channel behavior: observed candidates are stashed
on _extra_candidates and exposed through .candidates.
Single-outcome point-variant effects (Missense, FrameShift, etc.) are left
untouched even when the resolver has evidence — those classes
don't expose a multi-candidate view, and replacing them with a
multi-outcome wrapper would break downstream isinstance checks.
Producers that need to surface RNA observations on point variants
should report them as a separate :class:MultiOutcomeEffect rather
than mutating an existing single-outcome one. (The point-variant
diff is generally already correct from DNA, so this is rarely an
issue in practice.) Single-outcome structural calls (e.g. Intronic) are
wrapped in StructuralVariantEffect when observations exist, retaining the
DNA classification alongside the imported models.
Safe to call on a mixed collection where only some variants have
RNA evidence; no-op when resolver is None or doesn't implement
the protocol.
Returns effects for chaining convenience.
Source code in varcode/rna_evidence.py
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 | |
varcode.make_rna_outcome(effect, *, source: str = 'rna', transcript_model_id: Optional[str] = None, read_count: Optional[int] = None, extra_evidence: Optional[Mapping[str, Any]] = None) -> EffectCandidate
¶
Construct an :class:~varcode.effect_candidates.EffectCandidate
carrying RNA-derived provenance.
Convenience factory for the common fields a reads-based or
long-read assembly tool wants on each observed outcome — keeps
consumers from hand-rolling the evidence dict shape and lets
downstream code rely on a small set of well-known keys.
| PARAMETER | DESCRIPTION |
|---|---|
effect
|
The effect this RNA-observed outcome represents.
TYPE:
|
source
|
Producer name; defaults to
TYPE:
|
transcript_model_id
|
Stable ID of the observed transcript model from the producer.
Stored under
TYPE:
|
read_count
|
Supporting read count. Stored under
TYPE:
|
extra_evidence
|
Producer-specific extra fields, merged into the evidence dict
on top of the well-known keys above. Allows tool-native fields
(e.g.
TYPE:
|