Experiencer Refinement¶
The ConText experiencer axis records who a clinical finding is about. A finding under a Family History heading has a family section prior. Local cues refine that prior because a single sentence can switch subject ("the patient's mother has diabetes", "the organ donor was CMV-positive").
openmed.clinical.experiencer refines the experiencer of a governing span using local subject cues, distinguishing three subjects:
| Value | Subject | Example cues |
|---|---|---|
patient | the patient (default) | none cued |
family | a relative of the patient | mother, father, sibling, maternal, family history, FHx |
other | a non-patient, non-relative subject | donor, roommate, partner, coworker |
This axis is a hard safety boundary for coreference-style aggregation: a family-member or other-subject finding must not be merged into the patient record.
Refining assertions¶
refine_experiencer(spans, context_result, text=...) accepts clinical spans and an existing ClinicalContextResult or ClinicalAssertion, then returns RefinedExperiencerAssertion records. Each record preserves the incoming temporality, certainty, and negation axes while attaching the refined experiencer to the assertion.
from openmed.clinical import ClinicalAssertion, refine_experiencer
text = "The patient's mother has type 2 diabetes"
span = {"start": text.index("diabetes"), "end": len(text), "label": "CONDITION"}
context = ClinicalAssertion(temporality="recent", certainty="certain")
[result] = refine_experiencer([span], context, text=text)
result.assertion.experiencer
# 'family'
result.assignment.cue
# 'mother'
The lower-level resolve_experiencer(text, span, *, section_experiencer=None) API returns only the assignment provenance for one span.
Resolving a span¶
from openmed.clinical import resolve_experiencer
text = "The patient's mother has type 2 diabetes"
span = {"start": text.index("diabetes"), "end": len(text), "label": "CONDITION"}
result = resolve_experiencer(text, span)
# ExperiencerAssignment(experiencer='family', cue='mother',
# cue_offset=(14, 20), source='cue')
resolve_experiencer(text, span, *, section_experiencer=None) returns an ExperiencerAssignment:
| Field | Meaning |
|---|---|
experiencer | patient, family, or other. |
cue | The matched subject cue (lowercased), or None when defaulted. |
cue_offset | Half-open offsets of the cue in the source text, or None. |
source | cue, section, or default -- how the value was decided. |
Resolution order¶
- Cue -- the subject cue nearest the span, within the span's clause, wins. Resolution is scoped by sentence punctuation (
.,!,?,;) and the contrastive subject-switch markersbut,however, andwhereas, so a subject named in a previous clause does not leak across the boundary. Coordinatingandandordeliberately remain inside the same scope because they commonly join findings about one subject. On a tie the more specificothersubject wins overfamily. - Section prior -- when no cue is found and a
section_experienceris supplied (for examplefamilyunder a Family History heading), it is used. - Default -- otherwise the span is attributed to the
patient.
An explicit cue always overrides the section prior, so "the patient's father also has hypertension" resolves to family even inside a patient-default section.
German source text¶
Pass language="de" (or a German locale such as de-DE) to resolve_experiencer or refine_experiencer. assert_context(..., language="de") forwards that language to local subject refinement. Whole-word cues include Mutter, Vater, Großmutter, and Spender. An explicit Patient/Patientin subject nearer the finding can override the family prior. German contrastive conjunctions and line boundaries end cue scope; a word such as Muttersprachlerin does not match Mutter.
Supply sections=detect_sections(text, language="de") to assert_context to retain section boundaries and context-source provenance. German medication headers (Medikation, Aktuelle Medikation, Entlassmedikation) end family history scope. German normalization also recognizes whole frequency phrases such as zweimal täglich; it does not infer a schedule from an ambiguous phrase.
These additions have synthetic regression coverage. They do not establish German clinical qualification. Language packs beyond English and German still use the existing English local-subject rules in this resolver.
Notes¶
Resolution is deterministic and offline. Experiencer refinement is a cue-based heuristic and is not a substitute for clinician review; validate before any clinical use.