Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Normalize or rederive?

ferro exposes two entry points for canonicalizing an HGVS description, but they are different operations with different guarantees. This guide says what each does, which axes each supports, and when to reach for one over the other.

normalizerederive
what it takesan HGVS descriptionan HGVS description
what it doesshifts and re-spells the given description in placethrows the spelling away and re-derives from the denoted bases
axesevery axis — g/c/n/r/p/mgenomic only — g. (and m. on the two rCRS accessions)
confluencebest-effort (rule 3) — converges equivalent inputsconfluent by construction, over one window
needs a referenceyesyes

normalize — canonicalize a description you were handed

Use normalize when you already have a description and want its canonical form: 3′/5′ shifting and the recommendations’ preferred representation, applied to the spelling you passed in. It works on every axis, because a c./r./p. description carries information — reading frame, which transcript, a protein consequence — that a genomic base window cannot recover.

import ferro_hgvs

nz = ferro_hgvs.Normalizer(reference_json="…")
nz.normalize("NM_000088.3:c.100delA")   # -> "NM_000088.3:c.100del"

Converging equivalent inputs to one output is confluence — rule 3 of the normalization rules, which normalize targets on a best-effort basis: a handful of known residual defects remain, where two spellings of one variant still normalize to two strings. Those are tracked bugs, not the intended contract.

rederive — one canonical description per variant

Use rederive when the input’s spelling should carry no weight — when you want the description for a variant, regardless of how it happened to be written. rederive expresses the variant as the bases it denotes (a reference/alternate window) and derives a description from those bases alone, so two spellings of one variant reach one result:

nz.rederive("NC_TEST.1:g.14_15insACGTACGT")   # -> "NC_TEST.1:g.7_14dup"
nz.rederive("NC_TEST.1:g.7_14dup")            # -> "NC_TEST.1:g.7_14dup"

Because it re-derives from a genomic sequence window, rederive is genomic-only and refuses a transcript or protein axis. Project onto the axis you need afterwards if required.

rederive returns the alignment-derived form by default. Pass recommended_form=True to route the result through normalize for ferro’s recommended, reference-anchored form:

nz.rederive("NC_TEST.1:g.11del", recommended_form=True)   # 3′-shifted per the recommendations

rederive is the single-call form of the to_sequencesfrom_sequences round trip described in Deriving a description from sequences; read that guide for the mechanics and for the read-dependence cost of a window-local derivation.

Which one?

  • You have a description and want it in canonical form on its own axis → normalize.
  • You want the same description for a variant no matter how two callers spelled it, on a genomic axis → rederive.
  • You have raw bases (a reference/alternate window) rather than a description → from_sequences.