Electronic Clinical Quality Measures (eCQMs) are computed over structured data using CQL (Clinical Quality Language) logic against the QDM (Quality Data Model). Much of what a measure needs — a counseling note, a reason a service wasn't done, a symptom — lives only in free text. This skill uses OpenMed to lift those facts out of notes (on-device) and feed them into measure computation so numerators and valid exclusions aren't undercounted.
When structured codes under-capture a measure population and the evidence is in notes: documented exclusions ("patient declined screening"), numerator-relevant findings, or symptoms gating a measure. Use it alongside a certified measure engine — OpenMed supplements capture; it does not compute or certify the measure.
| Population | Meaning | Where OpenMed helps |
|---|---|---|
| IPP (Initial Population) | everyone the measure could apply to | usually structured (encounters, age) |
| Denominator | IPP meeting base criteria | mostly structured |
| Denominator Exclusion / Exception | valid reasons to remove from denom | notes: "declined", "medical reason", "not indicated" |
| Numerator | met the quality action | notes: counseling delivered, advice given, status documented |
import openmed
note = (
"Tobacco use screened today; patient is a current every-day smoker. "
"Cessation counseling provided and cessation medication offered."
)
result = openmed.analyze_text(note, output_format="dict")
# entities -> {text, label, confidence, start, end}
# Lift two measure-relevant facts (illustrative, for a tobacco-screening eCQM):
facts = {
"tobacco_status_documented": any(e["label"] in {"smoking_status", "tobacco_use"}
for e in result["entities"]),
"cessation_intervention_documented": "counseling" in note.lower(),
}
# These become QDM data elements your CQL references (see workflow).
Pick the model whose labels match the measure concept (choosing-openmed-models)
and code spans to value-set vocabularies via the linking skills before they
enter QDM.
openmed.deidentify on notes before any logging or
storage; keep the measure keyed by internal patient ids.openmed.analyze_text for the concepts the measure needs
(status, intervention, reason-not-done). Use resolving-clinical-context to
drop negated/hypothetical/family-history mentions — a negated exclusion is
not an exclusion.Assessment, Performed, Intervention, Performed,
Diagnosis) with the right author/relevant dates
(building-patient-timelines).cqframework engine). OpenMed
does not execute CQL.analyze_text entities + clinical temporality + the
linking skills (to land facts in the measure's value sets) + deidentify
upstream.etl-to-omop-cdm
rows if you compute measures on an OMOP store instead.openmed/processing/ (analyze_text), openmed.clinical
(temporality).