Experiencer Refinement¶
The ConText experiencer axis records who a clinical finding is about. The shipped layer resolves it only at the section level: a finding under a Family History heading is attributed to the family. Free text is finer-grained than that -- 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.
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.