openvax / openvax/varcode

Splice, germline-phase, haplotype and SV uncertainty don't compose

Open
#421 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
87
Forks
28
Avg merge
3h 27m
Merged PRs (30d)
27

Description

varcode models four kinds of uncertainty: splice outcome (SpliceOutcomeSet), unknown germline phase (PhaseCandidateSet), known-cis haplotypes (HaplotypeEffect) and SV alternatives (StructuralVariantEffect.candidates). Each is built by a separate code path, and when two of them apply to the same variant, one path either ignores the other or silently drops it.

All examples below are on main at 1f65898, CFTR ENST00000003084, Ensembl 81. The germline variant is a het SNV with no genotype, so phase is unknown.

Combination What comes back Problem
Splice donor SNV (7:117531115 G>A) + germline SNV in the last exon codon PhaseCandidateSet containing two SpliceOutcomeSets, identical in both hypotheses The germline is never applied. _classify_against_patient_baseline can't apply an intronic variant to cDNA, so it falls back to reference-relative annotation (germline.py:897-906, 919-923), and the phase axis adds a second level of nesting with no information in it.
DEL across exons 5–6 + germline SNV in window PhaseCandidateSet of ExonLoss, ExonLoss The germline path calls the point-variant classifier for the SV, bypassing the structural_variant annotator. Without germline=, the same DEL gives LargeDeletion.
Splice donor SNV + cis coding SNV, with a phase_resolver that reports cis Separate Substitution and SpliceOutcomeSet; no HaplotypeEffect build_haplotype_effects skips any group that apply_variants_to_transcript can't build, without a warning (phasing.py:358-360).
DEL + cis coding SNV, with a phase_resolver LargeDeletion and Substitution; no HaplotypeEffect Same silent skip.
DEL starting at donor +2 and running into the intron Intronic Splice outcomes attach only to StructuralVariantEffect (annotators/structural_variant.py:698), so a deletion of donor +3..+6 has no splice candidates. A 1 bp point deletion at +3 gives a SpliceOutcomeSet.
DEL starting at the last base of exon 5 (removes the donor GT) LargeDeletion with no splice candidates _breakpoint_splice_window looks only at intronic breakpoints (:193-213), so a breakpoint on the exon boundary never gets splice outcomes.

RNA evidence doesn't compose either. apply_rna_evidence_to_effects only looks at the top-level effect (rna_evidence.py:192-217). For a PhaseCandidateSet wrapping SpliceOutcomeSets, observed splice isoforms are appended to the outer phase set as extras, instead of reconciling the inner splice sets.

What these have in common: each source builds its own wrapper around the output of the path before it, and the paths don't hand off to each other. A shared model would fix all of them at once. For each hypothesis (phase × splice mechanism × SV junction), build one MutantTranscript and classify it. That's also the direction proposed in #420.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the interaction points named in germline.py, phasing.py, annotators/structural_variant.py, and rna_evidence.py, then read the direction in #420. Trace how each path wraps or skips effects before designing a shared hypothesis model. Done means the listed splice, phase, haplotype, SV, breakpoint, and RNA-evidence combinations compose without silently dropping information.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
bioinformatics
Issue type
Refactor
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.