entries
Turn one supplied CSV cell into observation-shaped facts.
A source states its measurements one of two ways, and this module reads both.
Config declares them, one column per measurement, each naming its own key and
unit (EnrichmentValueColumn); that is what code_root and default_unit
arrive as, and it is what a site export looks like. A cell may also carry a
JSON payload, which fans out below whatever code root it was given:
- A JSON object fans out to one fact per top-level key, coded
<code_root>_<key>. - A key whose value is itself
{value, unit}supplies both, and a unit the payload states always beats the column's configured one. - Anything else is one fact coded by
code_rootalone.
The two compose rather than compete: a JSON object inside a declared value
column codes <source>_<column key>_<json key>. Both routes mint the same
code shape, so a criterion cannot tell which produced a fact.
Every cell is parsed as JSON before anything else, so a cell holding -1
resolves to the number and not the string. This is deliberately the only place
that decides the mapping.
Module
Functions
entry_from_record
def entry_from_record(record: PatientEnrichmentRecord) ‑> dict[str, typing.Any]:Render one stored row as the observation entry criteria matching reads.
The shape matches an asdict()-serialised Observation, which is what
_build_observation_filter expects on the observations columns.
date is emitted as "%Y-%m-%d" and nothing longer. _coerce_event_datetime
also tolerates fuller ISO timestamps now and logs a warning on anything it
cannot parse, but this entry still emits date-only on purpose: measured_at
is part of the cache primary key, and date-only at the top level of a code
entry is the convention _stringify_datetimes in ehr_query/functions.py
establishes.
Arguments
record: The stored supplied-measurement row.
Returns The observation entry dict for this row.
facts_from_cell
def facts_from_cell( cell: Any, code_root: str, *, default_unit: str | None = None,) ‑> list[SuppliedFact]:Extract every fact a single supplied cell carries.
Arguments
cell: The raw cell value, JSON-encoded or a bare scalar.code_root: The code the facts are addressed by — the source name for a source declaring one value column, or"<source>_<key>"for one of several named value columns. A JSON object fans out below it, one fact per key.default_unit: The unit to stamp when the payload states none of its own. A plain numeric cell (0.18in a logMAR column) carries no unit, but a criterion comparing againstUnitBound(value="logMAR")needs one, and the column's configured unit is the only place that knowledge exists. A unit the payload does state always wins, so a{value, unit}object is never overridden.
Returns
One SuppliedFact per resolvable measurement; empty when the cell is
absent or carries nothing resolvable.
snellen_to_logmar
def snellen_to_logmar(text: str) ‑> float | None:A Snellen fraction as logMAR, or None when text is not one.
logMAR is log10(denominator / numerator), so 20/200 is 1.0 and
20/20 is 0.0 whatever reference distance the fraction is written at —
6/12 and 20/40 both give 0.301. Rounded to 3dp, which is finer than
any acuity chart's own granularity and keeps the stored number readable.
Only a fraction converts. Three groups of value deliberately do not:
- The low-vision tokens (
LP,HM,CF3,NLP). Their logMAR equivalents are convention rather than measurement, and a site already mapping them supplies the number in its logMAR column instead — the sample i-Lumen export carriesLPin Snellen alongside a real2.7in logMAR. - A bare number.
0.5is decimal visual acuity (0.301 logMAR) to one site and an already-converted logMAR reading to another, and there is nothing in the cell to say which. Guessing would put a wrong reading into the cache, where a criterion cannot tell it from a measured one. - A fraction carrying anything else (
20/40+2), or a nonsensical one (20/0,0/40). The letter modifier lives in its own column where a site states one.
Arguments
text: The raw Snellen cell.
Returns
The logMAR value, or None when text is not a plain fraction of
two positive numbers.
Global variables
-
SNELLEN_UNIT- The unit whose columns a Snellen sibling can supply a reading for.Compared case-insensitively against
EnrichmentValueColumn.unit, so the config's ownlogMARspelling matches.
Classes
SuppliedFact
class SuppliedFact( code_code: str, value_num: float | None, value_str: str | None, unit: str | None,):One measurement extracted from a supplied cell.
Attributes
code_code: The observation code this fact is addressed by.value_num: The numeric value, when the payload carried one.value_str: The string value, when the payload carried a non-numeric.unit: The unit, when the payload stated one.
Variables
- static
code_code : str
- static
unit : str | None
- static
value_num : float | None
- static
value_str : str | None