Skip to content

Release 2026.3.0 - #111

Open
bencap wants to merge 16 commits into
mavedb-mainfrom
mavedb-dev
Open

bencap wants to merge 16 commits into
mavedb-mainfrom
mavedb-dev

Conversation

@bencap

@bencap bencap commented Sep 21, 2026

Copy link
Copy Markdown
Collaborator

Features

  • Reverse Translation Mapping Support: project each measured variant onto its deterministically reachable layers (g↔c, nucleotide→p) via genomic-accession transcript selection, with typed mapping outcomes and assay-level preferred-layer selection (feat: Reverse Translation Mapping Support #108)
  • Add MappingOutcome schema definition and outcome field for detailed per-variant mapping results
  • Map non-RefSeq accession targets (Ensembl protein/transcript) to their RefSeq MANE counterparts, keeping annotation output consistent regardless of how a target was declared; also fixes the mapper crashing when a target has no record group of its own — fixes Mapping fails when a target does not appear in any variants. mavedb-api#679

Bug Fixes

  • VRS Correctness: recompute allele identity from normalized content instead of relying on stale cached digests, fixing incorrect IDs for deletions/duplications in repeat regions (feat: VRS Correctness #106)
  • Return the NM transcript (not the NC_ genomic accession) as the cDNA-layer mapped reference sequence
  • Correct strand detection and hit-range ordering for minus-strand protein alignments
  • Prevent null-layer re-attribution from duplicating mapped_scores records at the preferred layer
  • Remove incorrect underscore from the Ensembl protein ID accession check (fix: Remove underscore from check for Ensembl Protein ID #110)

Maintenance

  • Minor readability cleanup in transcript selection
  • Add .claude to .gitignore

bencap and others added 16 commits June 3, 2026 11:11
Add `vrs_utils.identify_allele` and `normalize_and_identify`, and switch
`vrs_map._construct_vrs_allele` to use them in place of direct
`ga4gh_identify` calls. The GA4GH Merkle-tree caches sub-object digests
on the object after first identification, so any subsequent mutation
(notably the pre-map `refgetAccession` swap, normalization, or state
coercion) leaves a stale id unless the cached digests are cleared first.
Clearing both the location and allele digests before identification
ensures the id always reflects current content.

- vrs_utils: new module centralizing the digest-correctness invariant
- vrs_map: route both the ref-identical and SNV/delins branches through
  the new helpers; the ref-identical branch also gains a reassigned
  `normalize` return value as a side-effect
- tests/test_vrs_utils: offline coverage for content-addressing, the
  stale-digest clearing invariant, the normalize+identify pairing, and
  the malformed-input error path
- align: incidental formatter-driven whitespace tweak
Add MappingOutcome so every (variant, level) record carries a typed outcome,
distinguishing a benign absence (intronic, no protein consequence) from a
genuine failure that error_message alone cannot convey. Derive the preferred
(authoritative) layer from the target's assay level rather than always
preferring genomic.
…c projection

Select a coding transcript for NC_ protein-coding targets via Ensembl locus
overlap plus MANE, so they are no longer silently skipped by reverse
translation. Project each measured variant onto its deterministically
reachable layers (g<->c, nucleotide->p), emitted as typed-outcome records and
routed by preferred_layer_only.
…ferred-layer records

- Track represented variant IDs at the preferred layer; re-attribute
  only variants that have no preferred-layer record, avoiding duplicate
  mapped_scores for variants with both a dead genomic attempt and a
  measured protein record (e.g. codon-optimised targets).
- Synthesize a preferred-layer failure for variants that mapped only at
  a non-preferred layer (e.g. wild-type p.= on a genomic-preferred
  target) so every input variant always has exactly one output record.
- Extract _map_protein_layer in vrs_map to return (mapping, reason)
  instead of an ad-hoc error MappedScore; a row that maps at no layer
  is failed once, layer-agnostically, carrying the detailed reason.
- Add TestNullFailureDedup and TestMapProteinLayerReason test coverage.
…ignments

  For protein-vs-DNA BLAT alignments, qcoords always increase (protein
  reads N→C regardless of genome strand), so they cannot be used to
  detect strand. Switch to tcoords direction for protein queries.

  Also normalise hit_subranges and hit_range entries with min/max so
  they are always in ascending order, which they are not when the target
  gene sits on the minus strand.

  - Use tcoords direction (not qcoords) for strand detection when
    -q=prot is in blat_params
  - Wrap hit_subrange and hit_range endpoints in min/max in both
    _get_best_match and align_target_to_protein
  _get_mapped_reference_sequence had no CDNA branch, so it fell through
  to the genomic chromosome lookup and returned the NC_ accession as the
  post_mapped reference for the cdna layer. This caused target_genes
  post_mapped_metadata to carry NC_000017.11 under the "cdna" key
  instead of the NM transcript.

  Add a CDNA branch that resolves the NM/ENST accession from
  tx_output.nm (preferred, covers NC_/sequence-based targets) or from
  the target's own accession when it is already an NM_/ENST (cdna-source
  targets). Returns None rather than a chromosome when no NM is
  resolvable. Also adds unit tests for all three layer paths.
There is no underscore in Ensembl IDs so removing it here.
…rotein-id-check

fix: Remove underscore from check for Ensembl Protein ID
…ant-projection

feat: Reverse Translation Mapping Support
- Reindent the all([...]) call in _offset_target_sequence to hug the
  brackets instead of nesting the list on its own lines
- Bind target = scoreset_metadata.target_genes[target_gene] in
  select_transcripts to shorten downstream accesses
…unterparts

Accession-based targets declared with Ensembl protein (ENSP) or transcript
(ENST) accessions previously passed through as bare, unresolved accessions or
were dropped, leaving downstream annotation inconsistent with the RefSeq
accessions used elsewhere in the pipeline. Resolving them to their RefSeq MANE
counterpart keeps output consistent regardless of how the target was declared.

- add get_gene_symbol_from_ensembl_protein / _transcript lookups as the bridge
  from a non-RefSeq accession to get_mane_transcripts_for_gene
- add _select_refseq_protein_counterpart / _select_refseq_cdna_counterpart,
  falling back to the bare accession (protein) or None (cDNA, since np is
  required on TxSelectResult) when no counterpart resolves
- skip standalone VRS mapping for a target with no record group of its own
  (e.g. base-editor score sets where every row groups under the cDNA target)
  instead of KeyError'ing on records[target_gene]
- re-raise the original alignment error instead of losing its traceback via
  `raise AlignmentError from e`
identify_allele cleared the cached digests but called ga4gh_identify with the
default in_place, which only fills an empty id — and every allele reaching it
already has one, minted by AlleleTranslator over un-normalized content. Force
recomputation with in_place="always", and recompute location.id separately,
since ga4gh_identify writes only the id of the object it is handed. Only
deletions and duplications in repeat regions were affected; substitutions
normalize to themselves, so their pre-normalization id stayed correct by
coincidence and hid the bug.

Also look up vrs_ref_allele_seq by extension name rather than extensions[0],
which was correct only while it was the sole extension, and compute it only for
VRS 1.3 VariationDescriptors — VRS 2.x recovers the reference from
refgetAccession and coordinates, so computing it for 2.0 alleles cost a seqrepo
fetch per allele for a field nothing reads.
@coveralls

Copy link
Copy Markdown

Coverage Status

coverage: 0.0%. remained the same — mavedb-dev into mavedb-main

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mapping fails when a target does not appear in any variants.

3 participants