Source code for mir.embedding.presets

"""Recommended per-chain presets: prototype count and PCA dimensionality.

Data-driven from the bundled prototypes (measured by the ``benchmarks/`` scripts in the companion
``2026-mirpy-analysis`` repo):

* **n_prototypes** — the pairwise-distance geometry saturates (Pearson r vs a 5000-prototype
  reference ≥ 0.996 at 1000, ≥ 0.999 at 2000). Compact chains (IGK/IGL/TRG) saturate earlier;
  diverse chains (IGH/TR*) benefit from 2000. The paper's 3000 is safe but generous.
* **n_components** — PCA dimensions retaining ~95% variance (the paper's clustering regime).
* **n_components_recon** — PCA dimensions retaining ~99% variance, needed to *reconstruct*
  the longer, more diverse junctions with the inverse codec (Theory T5, arda coords: IGH
  exact-match 0.115 at 95% → 0.356 at 99%). Compact chains barely differ; IGH/TRD/TRA need many more.

Values are rounded up to the nearest 5; treat them as starting points, not hard limits.
"""

from __future__ import annotations

from dataclasses import dataclass

from mir.aliases import normalize_locus_alias, normalize_species_alias


[docs] @dataclass(frozen=True) class ChainPreset: """Recommended settings for one (species, locus).""" n_prototypes: int # prototype count (embedding geometry saturated) n_components: int # PCA dims for embedding / clustering (~95% variance) n_components_recon: int # PCA dims for codec reconstruction (~99% variance)
# keyed by (canonical species, canonical locus) CHAIN_PRESETS: dict[tuple[str, str], ChainPreset] = { ("human", "TRA"): ChainPreset(2000, 65, 220), ("human", "TRB"): ChainPreset(2000, 65, 260), ("human", "TRG"): ChainPreset(1000, 25, 100), ("human", "TRD"): ChainPreset(2000, 65, 280), ("human", "IGH"): ChainPreset(2000, 65, 300), ("human", "IGK"): ChainPreset(1000, 20, 65), ("human", "IGL"): ChainPreset(1000, 20, 65), ("mouse", "TRA"): ChainPreset(2000, 50, 150), ("mouse", "TRB"): ChainPreset(2000, 55, 225), } # generic fallback for a chain without a measured preset (diverse-chain defaults) _FALLBACK = ChainPreset(2000, 60, 250)
[docs] def get_preset(species: str, locus: str) -> ChainPreset: """Return the :class:`ChainPreset` for a (species, locus), aliases resolved. Falls back to a generic diverse-chain preset for unmeasured combinations. Example: >>> get_preset("human", "IGH").n_components_recon 300 >>> get_preset("hsa", "beta").n_prototypes 2000 """ key = (normalize_species_alias(species), normalize_locus_alias(locus)) return CHAIN_PRESETS.get(key, _FALLBACK)
if __name__ == "__main__": assert get_preset("hsa", "beta").n_prototypes == 2000 assert get_preset("human", "IGH").n_components_recon == 300 assert get_preset("mouse", "TRA").n_components == 50 assert get_preset("human", "TRD") is CHAIN_PRESETS[("human", "TRD")] print("mir.embedding.presets self-check OK") print(f"{'chain':<12}{'n_proto':>8}{'PCs(95%)':>9}{'PCs(99%)':>9}") for (sp, lo), p in CHAIN_PRESETS.items(): print(f"{sp+'_'+lo:<12}{p.n_prototypes:>8}{p.n_components:>9}{p.n_components_recon:>9}")