Category-Aware Routing
The mapper is a laboratory mapper, not a universal clinical-document mapper. It first identifies the observation domain and then uses LOINC laboratory classes as retrieval facets. This reduces unrelated candidates while keeping the complete release in one SQLite source of truth.
Observation Contract
All routing fields are optional, so existing integrations continue to work:
from loinc_mapper import LabObservation
observation = LabObservation(
raw_name="Hemoglobin",
value="14.2",
unit="g/dL",
specimen="whole blood",
observation_domain="LAB_RESULT",
loinc_class_hint="HEM/BC",
panel_context="CBC",
)
| Field | Meaning |
|---|---|
observation_domain |
LAB_RESULT today; imaging and documents belong to future adapters |
loinc_class_hint |
Official LOINC class such as CHEM or UA |
panel_context |
Context such as CBC, CMP, or lipid panel |
class_source |
Evidence origin, such as explicit, report_metadata, or panel_context |
class_confidence |
Confidence in the class evidence, from 0.0 to 1.0 |
Supported Classes
| Clinical grouping | LOINC class |
|---|---|
| Chemistry | CHEM |
| Coagulation | COAG |
| Hematology/blood counts | HEM/BC |
| Urinalysis | UA |
| Serology | SERO |
| Microbiology | MICRO |
These are grouping fields, not replacements for LOINC Component, Property, Time, System, Scale, and Method. A class is advisory retrieval/ranking evidence only. Specimen, unit/property, method, time, and scale decide clinical compatibility.
Routing Modes
| Evidence | Behavior |
|---|---|
| Explicit or trusted report metadata | Strong class boost; laboratory-wide fallback remains available |
| Panel or report-section context | Soft class evidence and ranking feature |
| Unknown class | All laboratory terms only (CLASSTYPE=1) |
| Non-laboratory domain | Abstain before laboratory retrieval |
For example, Hemoglobin can refer to a whole-blood hematology observation,
urine hemoglobin, or a related chemistry observation. The class hint helps,
but the system still validates specimen and units. A wrong HEM/BC section
must not reject a clinically compatible CRP, TSH, endocrine, or chemistry
candidate. LAB_RESULT/CLASSTYPE=1 is the hard scope; class is not.
Storage and FAISS
assets/loinc/2.82/catalog_v5.sqlite3 contains one authoritative terms
table with class_name and class_type, plus indexed aliases and FTS5. The
catalog is not copied into six separate databases.
The compiled schema also preserves the release's COMMON_TEST_RANK and
ORDER_OBS fields. Common-test rank can prioritize frequently used candidates,
but rare codes remain reachable through fallback retrieval. ORDER_OBS is a
hard result-row guard: a row cannot emit an order-only panel code.
FAISS remains a semantic recall sidecar. Because FAISS does not apply a SQL metadata predicate, the mapper over-retrieves laboratory hits, records class agreement as ranking evidence, and then applies six-axis/unit safety validation. A class-specific FAISS shard may be searched first for latency, but a laboratory-wide fallback remains mandatory.
Screening Seed Audit
The Toward Health seed files are review input, not automatic registry data:
$env:PYTHONPATH = "$PWD\src"
python -m loinc_mapper audit-screening `
--catalog assets/loinc/2.82/catalog_v5.sqlite3 `
--input data/initial_labs_data_temp/toward_health_screening_loinc_cpt_mapping.csv `
data/initial_labs_data_temp/toward_health_screening_specialty_questionable.csv `
data/initial_labs_data_temp/toward_health_screening_top500.csv `
--output evaluation/screening/toward_health_screening_audit.json
The audit checks whether a code exists, is active, belongs to laboratory
class type 1, and agrees with the pinned release name. Name differences are
sent to clinical review rather than silently accepted. Blank-code proprietary
outputs remain vendor_specific_no_exact_code when the source notes that no
universal code was confirmed.
Only an expert-reviewed row with an active code, verified term, correct class,
system, property, method, units, vendor definition, and
verification_status=verified_active may be promoted to the high-trust
registry.
For recurring laboratories, keep source evidence in the governed
source_mapping_evidence registry layer or in a screening draft. Include the
laboratory's local test identifier, exact report surface, specimen, result
style, units, method, source document, reviewer, effective date, and LOINC
release. This creates a maintained local-test map without adding Python regex
rules. It can boost a matching local result but cannot prevent universal
retrieval for an unseen laboratory. See Universal multi-lab mapping.
Review Registry Draft
To prepare candidate aliases for doctor review without activating them:
python -m loinc_mapper build-screening-registry `
--catalog assets/loinc/2.82/catalog_v5.sqlite3 `
--input data/initial_labs_data_temp/toward_health_screening_loinc_cpt_mapping.csv `
data/initial_labs_data_temp/toward_health_screening_specialty_questionable.csv `
data/initial_labs_data_temp/toward_health_screening_top500.csv `
--output config/mapping_registry.screening_draft.json
The draft contains seed names, LOINC release aliases, vendor-specific names,
required units, class/specimen/property/method evidence, ambiguous aliases,
and blocked proprietary or invalid rows. It is marked review_draft; the
runtime registry loader rejects it so it cannot accidentally become active.
Doctors should change only clinically approved entries from
needs_clinical_review to approved. Then promote those entries:
python -m loinc_mapper promote-screening-registry `
--input config/mapping_registry.screening_draft.json `
--registry config/mapping_registry.json `
--catalog assets/loinc/2.82/catalog_v5.sqlite3 `
--output config/mapping_registry.reviewed.json `
--reviewer "Doctor name"
Ambiguous surface names are deliberately withheld instead of being assigned to whichever code has the highest lexical score. LOINC release aliases are already available through the catalog and do not need to be copied into the active registry unless a reviewer approves a local/vendor interpretation.