Phasing and germline API¶
See Phasing and Germline-aware annotation for input requirements and examples.
Phasing¶
varcode.ReadPhasingSource
¶
Bases: Protocol
Reports per-variant read-level evidence and co-occurring partners.
The minimum interface needed to establish cis from read-level data — co-observation on the same supporting reads, same long-read fragment, same assembled contig, etc. Implementations decide how strong the evidence is; consumers only see a boolean membership question.
Partners alone never establish trans: a variant missing from another's
partners may simply be uncovered or outside the source's input. A
source that observes one variant's alt allele together with the
other's reference allele reports trans by also implementing
in_cis(v1, v2, transcript=None), which returns True, False
or None.
has_evidence(variant) -> bool
¶
partners_in_cis(variant) -> Sequence
¶
Variants observed in cis with variant — i.e. on the
same supporting reads / fragment / contig. May include
germline SNPs, nearby somatic variants, or variant itself
(implementations pick their convention). Empty sequence when
no evidence covers variant.
Source code in varcode/phasing.py
varcode.MutantTranscriptSource
¶
Bases: Protocol
Reports an observed mutant transcript for (variant, transcript).
Independent of phasing. A source can implement just
:class:ReadPhasingSource, just :class:MutantTranscriptSource,
or both. Consumers iterating effects use this channel to substitute
the observed mutant protein (from RNA assembly, long-read calling,
etc.) for the reference-inferred one.
mutant_transcript(variant, transcript)
¶
The :class:~varcode.MutantTranscript for
(variant, transcript), or None when this source has
no observed transcript for that pair.
varcode.MolecularPhaseResolver(phasing_source: ReadPhasingSource)
¶
Phase resolver backed by a :class:ReadPhasingSource (#269, #259).
Two variants are cis if the source reports them as co-observed.
That's direct molecular evidence — not a probabilistic call. Not
being co-observed is not evidence of trans, so without the source's
own in_cis the answer is then None.
Usage::
# Any object satisfying ReadPhasingSource works. Common
# implementation: an Isovar adapter shipped by openvax/isovar.
resolver = MolecularPhaseResolver(source)
effects = variants.effects(phase_resolver=resolver)
If source also satisfies :class:MutantTranscriptSource, the
resolver routes :meth:mutant_transcript calls to it — so any
effect whose (variant, transcript) is covered by the source
gets its :attr:~MutationEffect.mutant_transcript populated with
the observed mutant transcript.
Sources may also expose their own in_cis(v1, v2, transcript=None)
method. When present, the resolver delegates to that method instead
of reducing through :meth:ReadPhasingSource.partners_in_cis. This
is how direct-read sources report trans from co-covering fragments
and None for pairs without enough of them.
Source code in varcode/phasing.py
has_evidence(variant) -> bool
¶
mutant_transcript(variant, transcript)
¶
Return the observed :class:MutantTranscript for
(variant, transcript), or None when the wrapped source
doesn't implement :class:MutantTranscriptSource or has no
transcript for that pair.
Source code in varcode/phasing.py
in_cis(v1, v2, transcript=None) -> Optional[bool]
¶
Return the source's own in_cis answer when it has one.
Otherwise True when the source reports v1 and v2 as
co-observed and None when it doesn't: a variant missing from
the other's partners may be uncovered, so partners alone never
establish trans.
transcript is accepted for interface symmetry with
:class:VCFPhaseResolver.in_cis and passed to the source's own
in_cis; the partners fallback is isoform-agnostic.
Source code in varcode/phasing.py
phased_partners(variant, transcript=None) -> Sequence
¶
Variants co-observed with variant — i.e. the cis set.
Empty when the source has no evidence for variant.
Source code in varcode/phasing.py
varcode.ReadPhaseResolver(phasing_source: ReadPhasingSource)
¶
Bases: MolecularPhaseResolver
Compatibility name for :class:MolecularPhaseResolver.
The old name is kept because it shipped in varcode 5.0.0. New code
should prefer :class:MolecularPhaseResolver, which better describes
sources backed by reads, paired fragments, assembled contigs, or other
direct molecular evidence.
Source code in varcode/phasing.py
varcode.RNAReadPhasingSource(bam_path: str, *, variants=None, min_mapping_quality: int = 20, min_base_quality: int = 20, min_alt_reads: int = 2, phasing_error_rate: float = 0.01, max_p_value_for_phasing: float = 0.05, max_distance_from_read_edge: Optional[int] = 5, require_proper_pair: bool = True, skip_duplicates: bool = True, skip_secondary: bool = True, skip_supplementary: bool = True)
¶
BAM-backed phasing source for RNA read co-occurrence.
This is the lightweight alternative to an Isovar-style assembly
source. It reads quality-filtered alignments from an RNA-seq BAM and
answers whether variants are observed on the same read or paired-end
fragment. It does not assemble contigs and does not provide
mutant_transcript; callers that need observed mutant proteins
should use an assembly-backed source.
Usage::
source = RNAReadPhasingSource("tumor.rna.bam")
resolver = MolecularPhaseResolver(source)
effects = variants.effects(phase_resolver=resolver)
| PARAMETER | DESCRIPTION |
|---|---|
bam_path
|
Coordinate-sorted, indexed BAM path.
TYPE:
|
variants
|
Optional universe used by :meth:
TYPE:
|
min_mapping_quality
|
Minimum MAPQ for reads contributing evidence.
TYPE:
|
min_base_quality
|
Minimum base quality for SNV/MNV and insertion allele calls.
TYPE:
|
min_alt_reads
|
Minimum alt-supporting reads/fragments required for
TYPE:
|
phasing_error_rate
|
Chance that a read shows the wrong allele at a variant's locus, from sequencing error, RNA editing or mismapping. Raise it for error-prone reads, such as ONT's.
TYPE:
|
max_p_value_for_phasing
|
One-sided binomial p-value at or below which :meth:
TYPE:
|
max_distance_from_read_edge
|
Discard allele calls whose queried bases are closer than this
many bases to either read edge. Set to
TYPE:
|
require_proper_pair
|
For paired reads, discard fragments not marked proper pair. Unpaired reads are still accepted.
TYPE:
|
skip_duplicates
|
Standard SAM flag filters.
TYPE:
|
skip_secondary
|
Standard SAM flag filters.
TYPE:
|
skip_supplementary
|
Standard SAM flag filters.
TYPE:
|
Source code in varcode/rna_read_phasing.py
close()
¶
register_variants(variants)
¶
Register variants used by :meth:partners_in_cis.
This is optional for ordinary MolecularPhaseResolver.in_cis use,
where both queried variants are registered automatically.
Source code in varcode/rna_read_phasing.py
register_haplotype(variants, *, flanking_bases=5)
¶
Test a known local allele combination by its anchored RNA sequence.
| PARAMETER | DESCRIPTION |
|---|---|
variants
|
Nonoverlapping substitutions/deletions on one genome and contig. All alternate alleles form one hypothesis, not an assumed phase. Register competing hypotheses separately when necessary.
TYPE:
|
flanking_bases
|
Unchanged reference bases required on each side (default five).
TYPE:
|
Notes
A match requires the entire sequence, including both flanks, on ONE alignment, with the configured base-quality and read-edge filters. Equivalent D/N/split-gap encodings can then support the same known sequence. This does not establish a genomic deletion from an RNA skip. A fully covered high-quality mate with a different sequence vetoes that fragment's support. Missing coverage and low-quality context do not. Reference is fetched from the variants' genome; unavailable sequence, overlapping edits and reference mismatches raise ValueError. No BAM bases are corrected, no missing bases filled, and no mates assembled. Registered variants use these full-context matches instead of individual CIGAR calls. Nonmatches remain unknown, not reference/trans evidence.
Source code in varcode/rna_read_phasing.py
supports_variant(variant) -> Optional[int]
¶
Count quality-filtered reads/fragments supporting variant.alt.
Returns None when the variant's contig is absent from the BAM.
Results are cached until a new haplotype is registered.
Source code in varcode/rna_read_phasing.py
has_evidence(variant) -> bool
¶
True if the BAM has enough alt-supporting reads/fragments.
in_cis(v1, v2, transcript=None) -> Optional[bool]
¶
Return cis/trans from RNA read or fragment co-occurrence.
Decided by :func:four_gamete_phase from the fragments covering
both loci: True when both alt alleles are seen together beyond
read errors and not each alone, False when each is seen alone
and not together, None otherwise.
Source code in varcode/rna_read_phasing.py
partners_in_cis(variant) -> Sequence
¶
Known registered variants observed in cis with variant.
Source code in varcode/rna_read_phasing.py
varcode.VCFPhaseResolver(variant_collection, sample)
¶
Phase resolver backed by VCF GT + PS FORMAT fields.
Reads the phase data that varcode's VCF loader already parses
into :class:~varcode.Genotype (via #267): whether the
GT delimiter was | (phased) or / (unphased), the
PS phase-set identifier, and the per-haplotype allele indices
in :attr:Genotype.alleles.
Two variants are cis when they sit in the same phase set on
the same haplotype slot, trans when they sit in the same
phase set on different slots, and the resolver returns None
("no evidence") for variants that aren't both phased, don't share
a phase set, or lack called alleles.
Compatible with any tool that writes standard-shaped VCF:
WhatsHap, HapCUT2, DeepVariant, GATK HaplotypeCaller, long-read
callers (PEPPER-DeepVariant, Clair3), population phasers
(SHAPEIT5, Eagle2). varcode doesn't care which one wrote the
file — it only reads GT and PS.
Multi-allelic sites are handled: varcode splits those rows into
one :class:~varcode.Variant per ALT, each with an
alt_allele_index preserved on the
:class:~varcode.VariantCollection metadata. The resolver maps
each variant to its GT-encoded index and asks "which haplotype
slot carries this specific alt?".
Single-sample by construction. Phase is per-sample; multi-sample VCFs need one resolver per sample.
Currently supplies the cis/trans query but does not attach a
:class:~varcode.MutantTranscript — DNA phasing alone doesn't
produce an assembled contig. The natural next step is a
HaplotypeEffect / multi-variant apply_variants_to_transcript
helper that, when two or more cis variants overlap the same
transcript, builds a single joint :class:MutantTranscript
applying all edits at once. That's a separate PR — this
resolver already has the inputs it needs (in_cis) to drive
the grouping.
Source code in varcode/phasing.py
in_cis(v1, v2, transcript=None) -> Optional[bool]
¶
Return True if v1 and v2 are on the same
haplotype in the same phase set, False if they're on
different haplotypes in the same phase set, None when
the phase relationship can't be determined (unphased GT,
different phase sets, uncalled alleles).
transcript is accepted for interface symmetry with
:class:MolecularPhaseResolver.in_cis but isn't consulted —
DNA-level phase is isoform-agnostic.
Source code in varcode/phasing.py
phased_partners(variant, transcript=None)
¶
Variants in the collection that are cis with variant
under this resolver — i.e. sit in the same phase set on the
same haplotype slot. Empty when variant isn't phased or
has no called alt in the sample.
Source code in varcode/phasing.py
varcode.apply_phase_resolver_to_effects(effects, phase_resolver)
¶
Post-process an :class:EffectCollection (or any iterable of
:class:MutationEffect) to attach observed
:class:MutantTranscript objects when the resolver has evidence.
Mutates each effect in place by setting
effect.mutant_transcript. Effects whose transcript isn't
resolvable or whose (variant, transcript) has no observed
transcript are left untouched — so this is safe to call on a mixed
collection where only some variants have RNA evidence.
Source code in varcode/phasing.py
varcode.query_in_cis(phase_resolver, v1, v2, transcript=None) -> Optional[bool]
¶
Ask phase_resolver whether v1 and v2 are in cis.
Returns True (cis), False (trans) or None (unknown). NumPy
booleans count as booleans. No resolver, a non-boolean answer, or a
resolver error gives None; errors are logged as warnings so a
broken resolver is visible without failing annotation. transcript
is passed only when given, so two-argument resolvers keep working.
Source code in varcode/phasing.py
Germline-aware annotation¶
varcode.GermlineContext(variants: 'VariantCollection', completeness: Completeness = Completeness.COMPLETE, reference_name: Optional[str] = None, metadata: Mapping[str, Any] = dict(), max_phase_hypotheses: int = DEFAULT_MAX_PHASE_HYPOTHESES)
dataclass
¶
The patient's germline, packaged with completeness metadata and reference-build info for cross-VCF validation.
Construct via the from_* classmethods rather than instantiating
directly; the constructors apply the input-shape-specific
validation each route needs.
| ATTRIBUTE | DESCRIPTION |
|---|---|
variants |
The germline variants as a :class:
TYPE:
|
completeness |
How to interpret absence-of-a-call (see :class:
TYPE:
|
reference_name |
The genome reference these variants were called against —
TYPE:
|
metadata |
Open-ended dict for caller-supplied annotations (source caller name, sample identifier, normalization tool, etc.). Not interpreted by varcode; rides along for downstream consumers and serialization.
TYPE:
|
max_phase_hypotheses |
Most cis/trans phase hypotheses to enumerate for one somatic
variant (default 8, i.e. up to three unphased germline variants
nearby). Beyond it, effects are
:class:
TYPE:
|
Examples:
Route 1 — full germline call set::
ctx = GermlineContext.from_germline_vcf("normal.vcf")
Route 2 — multi-sample VCF, extract a column. The user must declare completeness explicitly because absence-from-a-multi- sample column rarely means ref/ref::
ctx = GermlineContext.from_multi_sample_vcf(
"merged.vcf", sample="NORMAL", completeness=Completeness.SPARSE)
Direct construction (tests, custom pipelines)::
ctx = GermlineContext.from_variants(
germline_variants, completeness=Completeness.COMPLETE,
reference_name="GRCh38")
Explicit empty context — opt-in to reference-relative fallback::
ctx = GermlineContext.empty()
from_germline_vcf(path: str, *, completeness: Completeness = Completeness.COMPLETE, metadata: Optional[Mapping[str, Any]] = None, **load_vcf_kwargs) -> 'GermlineContext'
classmethod
¶
Load a full germline VCF into a context.
load_vcf_kwargs are passed through to
:func:varcode.load_vcf — for example genome= or
only_passing=False. The returned context defaults to
Completeness.COMPLETE; pass completeness= only if the
VCF is something other than a real germline call set.
Source code in varcode/germline.py
from_multi_sample_vcf(path: str, sample: str, *, completeness: Completeness, metadata: Optional[Mapping[str, Any]] = None, **load_vcf_kwargs) -> 'GermlineContext'
classmethod
¶
Load a multi-sample VCF and extract one sample's calls as the germline.
completeness is required (no default) — multi-sample VCFs
from somatic callers (Mutect2's NORMAL column, e.g.) are
almost always sparse, but pure-germline multi-sample VCFs
(1000G, gnomAD batch genotyping) are complete. Forcing the
caller to declare prevents subtle correctness bugs from
treating a sparse column as if absence implied ref/ref.
The sample is filtered post-load. If you need per-sample
zygosity information, pass include_info=True (the default)
and consult vc.metadata[variant]["sample_info"][sample]
downstream.
Source code in varcode/germline.py
from_variants(variants, *, completeness: Completeness = Completeness.COMPLETE, reference_name: Optional[str] = None, metadata: Optional[Mapping[str, Any]] = None) -> 'GermlineContext'
classmethod
¶
Construct from an already-built :class:VariantCollection
or any iterable of :class:Variant objects.
Useful for tests, hand-built pipelines, and downstream tools
that already have variants in memory and don't need to re-parse
a VCF. reference_name should be passed explicitly when not
carried by the variants themselves; otherwise cross-VCF
validation will be a no-op.
Source code in varcode/germline.py
empty() -> 'GermlineContext'
classmethod
¶
Explicit no-germline context. Use this in pipelines where
germline= is structurally required but the caller has no
germline data — it documents intent better than passing
None, and downstream code can rely on the kwarg always
being a :class:GermlineContext.
Effect prediction with an empty context falls through to reference-relative annotation (no patient transcript construction), with no warnings — the caller has explicitly opted in to the fallback.
Source code in varcode/germline.py
homozygous(variants) -> Tuple
¶
The variants this context's sample carries on both haplotypes.
Needs genotypes for one sample: metadata["sample"] or the only
sample in :attr:variants. Without them nothing is reported.
Source code in varcode/germline.py
__bool__() -> bool
¶
Truthy when there's something to apply. EMPTY contexts
are falsy so if germline_context: reads idiomatically.
validate_against(somatic, *, validate_reference: bool = True) -> None
¶
Cross-validate this context with a somatic
:class:VariantCollection. Hard error on reference-build
mismatch unless validate_reference=False; warn on
suspicious shapes (empty germline, sparse coverage with no
overlap with somatic, etc.).
Called automatically by :meth:Variant.effects /
:meth:VariantCollection.effects when a context is supplied;
callers running validation manually can do so up front to fail
fast before annotation.
Source code in varcode/germline.py
variants_in_window(contig: str, start: int, end: int) -> Tuple
¶
Germline variants overlapping [start, end] on
contig (inclusive on both ends).
Used by the window-based lookup machinery (slice 2 of #268). Lazy interval index is built on first call and cached on the instance — subsequent calls are O(log N) per contig.
Returns a tuple (immutable) so callers can safely cache the result without worrying about the underlying index mutating.
Source code in varcode/germline.py
varcode.Completeness
¶
Bases: Enum
How exhaustive the germline call set is — the load-bearing flag that pins what absence of a call at a position means.
The same data structure ("a list of germline variants") can come from very different pipelines, and downstream effect prediction cannot make the right call without knowing which:
- If a position is absent from a real germline VCF emitted by a germline caller that examined the entire normal BAM, the patient is ref/ref there. Effect prediction proceeds reference-relative at that codon.
- If a position is absent from the
NORMALcolumn of a somatic-caller VCF, it likely means the somatic caller didn't emit a row — not that the position is ref/ref. The patient's germline state at that codon is unknown. The honest output is a possibility set including "unknown germline." - If a position is absent from a panel-of-normals filter list, it definitely doesn't imply ref/ref — the file only lists curated hotspots.
Mis-treating "absent" as "ref/ref" silently produces wrong germline-aware effects on somatic variants in long stretches of the genome the somatic caller never touched. The flag exists so that mistake fails loud (or at least produces an honest possibility set) instead of silently corrupting clinical annotation.
Values
+-------------------+-----------------------------------+--------------------------+
| Value | Typical pipeline of origin | Absence at a position |
+===================+===================================+==========================+
| :attr:COMPLETE | Germline caller (DeepVariant, | ⇒ ref/ref |
| | HaplotypeCaller, Strelka2 | |
| | germline) on the normal BAM | |
+-------------------+-----------------------------------+--------------------------+
| :attr:SPARSE | NORMAL column of a somatic | ⇒ unknown (probably |
| | tumor-vs-normal VCF (Mutect2, | ref/ref but not |
| | Strelka2 somatic, VarScan2 | queried). Honest output|
| | somatic) | is a possibility set. |
+-------------------+-----------------------------------+--------------------------+
| :attr:HOTSPOTS_ | Panel-of-normals filter list, | ⇒ definitely unknown. |
| ONLY | ClinVar pathogenic list, single- | Strictly weaker |
| | hotspot allowlists | evidence than SPARSE. |
+-------------------+-----------------------------------+--------------------------+
| :attr:EMPTY | "I have no germline data" — | n/a (no germline-aware |
| | explicit fallback, used so users | logic runs; equivalent to|
| | opt into reference-relative | not passing germline= at |
| | annotation rather than getting it | all) |
| | by accident from a missing kwarg | |
+-------------------+-----------------------------------+--------------------------+
What downstream slices do with this
Slice 3 of #268 wires germline= through annotator dispatch.
When a somatic variant lands in a transcript window that has no
germline calls, the annotator reads this flag to decide between:
COMPLETE→ patient is ref/ref in this window; emit a single reference-relative effect.SPARSE/HOTSPOTS_ONLY→ patient's germline is unknown in this window; emit a possibility set including the reference-relative effect plus "germline-unknown" outcomes so the user sees the uncertainty.EMPTY→ no germline-aware logic; reference-relative.
Constructors and defaults
:meth:GermlineContext.from_germline_vcf defaults to
COMPLETE because that's almost always what
a real germline VCF is.
:meth:GermlineContext.from_multi_sample_vcf requires the
caller to declare completeness explicitly (no default) — a
multi-sample VCF could be either, and silently defaulting
either direction is a correctness bug waiting to happen.
:meth:GermlineContext.empty always sets EMPTY.
varcode.predict_germline_aware_effect(somatic_variant, transcript, germline_ctx: GermlineContext, annotator, phase_resolver=None, window_fn=default_germline_window, max_hypotheses: Optional[int] = None)
¶
Predict the effect of somatic_variant on transcript
against the patient's germline-applied transcript.
Single entry point for germline-aware effect prediction.
:func:varcode.effects.predict_variant_effects calls this whenever
a non-empty :class:GermlineContext is supplied; otherwise it
bypasses the germline path entirely and the existing annotator
dispatch produces today's reference-relative output unchanged.
Behaviour by case:
- Somatic allele matches a germline allele — a
GermlineAlleleOverlap, without inferring zygosity, LOH, or a new allele sequence. - Phase cannot matter (no germline in the somatic's window, or a
noncoding or incompletely annotated transcript) — delegate to
annotator. With no germline nearby, SPARSE / HOTSPOTS_ONLY contexts mark the resulteffect.germline_unknown = True. - Phase known (resolver answers, homozygous germline, or a
hemizygous contig) — classify
against the single patient haplotype via
:func:
_classify_against_patient_baseline. - Phase unknown — classify each hypothesis and wrap them in a
:class:
~varcode.effects.effect_classes.PhaseCandidateSet. - Too many hypotheses — a :class:
~varcode.HypothesisLimitrecording the phase partition and the reference-relative effect.
max_hypotheses overrides germline_ctx.max_phase_hypotheses.
window_fn is the pluggable window selector — defaults to
:func:default_germline_window (codon-level, with splice-signal
expansion when the somatic is splice-adjacent). Callers that
need different windows pass their own.
Source code in varcode/germline.py
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 | |
varcode.apply_germline_to_transcript(transcript, germline_ctx, somatic_variant=None)
¶
Apply germline variants from germline_ctx to transcript,
returning the patient's baseline :class:MutantTranscript.
Lower-level entry point for callers that want the patient
transcript directly without going through full effect prediction.
Used internally by :func:predict_germline_aware_effect; exposed
publicly for downstream tools (Isovar, Exacto) that want to
compute a custom analysis on the patient haplotype.
Behaviour:
- If
germline_ctxis empty, returnsNone. - If
somatic_variantis provided, restricts germline to the somatic's window (per :func:default_germline_window); else applies all germline variants overlapping any exon of the transcript. - If germline edits conflict (overlapping cDNA ranges) or land
outside the CDS, returns
Noneand the caller falls back.
The returned object is the same shape that
:func:varcode.mutant_transcript.apply_variants_to_transcript
produces: a :class:MutantTranscript carrying the germline
edits with mutant_protein_sequence populated when the edits
land after the CDS start.
Source code in varcode/germline.py
varcode.partition_germline_by_phase(somatic_variant, germline_variants, phase_resolver=None, homozygous=(), cis_variants=()) -> PhasePartition
¶
Split germline_variants by their phase relative to somatic_variant.
Variants in homozygous sit on both haplotypes and are always cis,
as is every germline variant on a hemizygous contig (chrM, chrY; chrX
is treated as diploid, since Varcode has no sex information). The
rest are placed by :func:~varcode.phasing.query_in_cis answers
between every pair of variants, so phase can follow through another
germline variant. Variants whose phase is known only relative to each
other become linked groups. An answer that contradicts earlier
ones is ignored with a warning.
cis_variants supplies additional variants known to be in cis with
the somatic variant. They anchor the phase graph before resolver answers,
so germline phase can follow through any member of that group.
Homozygous alleles do not link the two haplotypes through this graph.
Source code in varcode/germline.py
889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 | |
varcode.PhasePartition(germline: Tuple = (), cis: Tuple = (), trans: Tuple = (), linked: Tuple = (), implicit: bool = False)
dataclass
¶
Bases: DataclassSerializable
Germline variants near a somatic variant, split by what is known about their phase relative to it.
germline holds every nearby germline variant in input order;
cis and trans are those whose phase relative to the somatic
variant is known, and :attr:unphased is the rest. linked lists
groups of unphased variants whose phase relative to each other is
known, as (one_haplotype, other_haplotype) pairs with the group's
first variant on one_haplotype; each group changes sides as a unit. implicit is true on hemizygous contigs
(chrM, chrY), where every germline variant is cis without evidence.
Build one with :func:partition_germline_by_phase.
blocks: Tuple
property
¶
Units of unknown phase as (one_haplotype, other_haplotype)
pairs: each linked group, then each other unphased variant.
hypothesis_count: int
property
¶
One hypothesis per assignment of each block to a haplotype.
hypotheses(max_hypotheses: int = DEFAULT_MAX_PHASE_HYPOTHESES) -> Tuple[PhaseHypothesis, ...]
¶
Enumerate phase hypotheses, keeping known phase fixed in each.
Known phase gives one hypothesis (phase_state "phased",
or "implicit" on hemizygous contigs). Otherwise there is one
"unknown" hypothesis per assignment of the :attr:blocks.
Haplotype labels depend only on the cis set: "A" when every
germline variant is cis, "B" when none is, otherwise
"A_mixed_<mask>" over :attr:germline.
| RAISES | DESCRIPTION |
|---|---|
HypothesisLimitError
|
When :attr: |
Source code in varcode/germline.py
varcode.enumerate_phase_hypotheses(somatic_variant, germline_in_window, phase_resolver=None, max_hypotheses: int = DEFAULT_MAX_PHASE_HYPOTHESES) -> Tuple[PhaseHypothesis, ...]
¶
Enumerate the phase configurations of somatic_variant
relative to germline_in_window.
Shorthand for :func:partition_germline_by_phase followed by
:meth:PhasePartition.hypotheses. Raises
:class:~varcode.HypothesisLimitError when the unphased variants
need more than max_hypotheses hypotheses.
Source code in varcode/germline.py
varcode.detect_loh(somatic_variant, germline_in_window) -> Optional[bool]
¶
Deprecated: these allele-only inputs cannot establish LOH.
Returns None (not assessed), never a positive or negative LOH call.
Use :func:detect_germline_overlap for the previous overlap query. LOH
requires an independently supported tumor/normal allelic-state assessment;
this annotation API does not perform that analysis.
Source code in varcode/germline.py
varcode.detect_germline_overlap(somatic_variant, germline_in_window) -> bool
¶
Whether the same allele occurs in the supplied germline variants.
Match reference assembly, contig, normalized position, REF, and ALT. This says nothing about genotype, allele balance, copy number, or LOH.
Source code in varcode/germline.py
varcode.GermlineAlleleOverlap(variant, transcript)
¶
Bases: TranscriptMutationEffect
This reported allele is already present in the supplied germline.
No new allele sequence is established. This does not assess allele dosage, loss of the other allele, expression, or the allele's pathogenicity.
Source code in varcode/effects/effect_classes.py
varcode.default_germline_window(somatic_variant, transcript) -> Tuple[str, int, int]
¶
Default window for looking up germline variants relevant to a somatic variant on a transcript.
Returns (contig, start, end) covering the codon containing the
somatic variant — three reference bases on each side of
somatic_variant.start. This is the window from #268's table
for in-exon coding variants.
Larger windows (splice signal region for splice-adjacent variants,
same exon for frameshift candidates) are useful refinements but
don't change the API. Callers that need them pass a custom
window_fn to :func:predict_germline_aware_effect.
Splice-adjacent: when the somatic is within 6bp of an exon-intron boundary, expand to a 12bp window centered on the boundary so germline edits to the donor / acceptor signal show up in the lookup. This catches the "germline broke the splice site" case without forcing the caller to wire up a separate window function.