cTAKES USDHUBClinician documentation
Word-sense disambiguationDefault-on USDHUB profileClinical status: not evaluated

WSD adds a decision only when one text span has competing concepts

The wrapper’s WSD keeps every candidate. It can mark one candidate as the preferred sense, or leave the group undecided when profiles are missing, direct evidence is absent, the score is weak, or the candidates are too close.

01

The ambiguity starts after dictionary lookup

Dictionary lookup can attach more than one CUI to the same source characters. That can happen because a word has multiple meanings, the terminology contains related candidates, or separate cTAKES annotation objects cover the same span.

The USDHUB graph/context annotator leaves candidate count and order intact. It owns only the WSD marker and within-group score fields, so the original dictionary candidates remain reviewable whether it decides or abstains.

tools.wsd.GraphContextWsdAnnotator is wrapper-owned code. It is not the stock Apache cTAKES/YTEX WSD component. Its profiles are built deterministically from the pinned dictionary and selected UMLS terms, definitions, semantic types, and bounded relations. It is not a neural model, does not learn from patient notes, and does not update itself during a run.

Two same-span candidates are scored together. A passing group receives Y and N while both rows remain; a failing group keeps both rows with blank WSD fields.
Figure 1. WSD owns only the disambiguation marker and score fields. It does not delete the original candidates.

Read the implementation: tools/wsd/GraphContextWsdAnnotator.java.

02

WSD changes the markers, not the candidate rows

PathWhose mechanismCandidate-row behaviorUSDHUB use
Apache/YTEX WSDThe separate Apache cTAKES/YTEX implementation.It has its own resources and output contract; this wrapper does not present it as the mechanism behind the USDHUB WSD columns.Not loaded by the reviewed production recipe.
USDHUB graph/context WSDWrapper-owned deterministic scorer.Retains every candidate. It writes one Y plus retained N alternatives only when profiles, direct evidence, score, and margin all pass; otherwise all WSD cells stay blank.Default on for the production star recipe; clinical status remains not-evaluated.
--no-wsdNo disambiguation annotator.Retains every candidate and leaves every WSD marker and score blank.Explicit recorded comparison, with a different analysis_id.

What changes inside one retained ambiguity group

StateCandidate ACandidate BRow count
WSD disabled with --no-wsdCUI retained; WSD fields blankCUI retained; WSD fields blank2
WSD enabled, evidence passesCUI retained; one candidate gets Y and scoreCUI retained; other candidate gets N and score2
WSD enabled, system abstainsCUI retained; WSD fields blankCUI retained; WSD fields blank2

Synthetic span: “mass” with context “near the right kidney”

Switch between a decision and an abstention

Body-structure0.682WSD = Y
Quantitative0.318WSD = N

Both rows remain. Complete profiles, direct evidence for the leading candidate, score, and margin allow Y and N to be written.

The synthetic body-structure candidate treats “mass” as a physical structure, while the quantitative candidate treats it as an amount or measurement. Those deliberately different senses make the scoring path visible; the phrase, candidate labels, codes, and numbers are teaching data, not a clinical result.

The default-on change makes this comparison explicit. A normal USDHUB run validates and uses the active WSD model. --no-wsd remains available for a controlled comparison and creates a different analysis_id.

03

The scorer combines five recorded evidence sources

For one ambiguity group, the annotator reads a bounded window around the source span, normalizes the words, and compares them with each candidate profile. The same group is scored together, which means the displayed values are relative to the competing candidates for that mention.

EvidenceWeightWhat it compares
Lexical context0.45Words and bigrams near the mention against the candidate’s ranked terminology profile.
Graph context0.35Other nearby concept candidates against a bounded UMLS relation neighborhood for the candidate.
Semantic type0.08The candidate’s UMLS semantic types against contextual concept/type evidence.
Preferred-term evidence0.07The local mention/context against the candidate’s preferred terminology label.
Prior0.05A bounded frequency/ranking prior from the built profile, used as the smallest component.
Sentence window
2
Character ceiling
1,200
Temperature
0.15
Minimum raw score
0.08
Minimum probability margin
0.35
Profile status
usdhub-wsd-v1

The temperature converts raw candidate scores into the displayed within-mention proportions. It does not calibrate the value against patient truth, diagnosis accuracy, or a clinician gold label.

Read the deterministic model builder: scripts/build_wsd_model.py. The dictionary page shows which terms can enter these profiles.

04

Four requirements must pass before the wrapper writes a decision

  1. Group all distinct CUI candidates on the same begin/end span, even when cTAKES created them on separate annotation objects.
  2. Clear any WSD-owned marker/score state from an earlier pass without changing candidate order.
  3. Load the model profile for every candidate. Any missing profile makes the group abstain.
  4. Calculate the five evidence components and weighted raw score.
  5. Require the leading candidate to have direct lexical, graph, or preferred-term evidence.
  6. Require the leading raw score to be at least 0.08.
  7. Normalize the group and require the leading candidate’s margin over the runner-up to be at least 0.35.
  8. When all four requirements pass, write one Y, N on the retained alternatives, and normalized scores that sum to one.
  9. When any requirement fails, leave every WSD field blank.
Sanity invariantFailure meaning
A singleton mention has blank WSD fields.There was no ambiguity group to resolve.
An abstention has blank flags and blank scores.The wrapper must not leave partial evidence looking like a decision.
A decision has exactly one Y.More or fewer winners makes the group internally invalid.
All decision flags are Y or N.No third state is serialized as a decision.
Scores are finite, within 0–1, and sum to one.The normalized group output is malformed.
05

The model is built for one exact dictionary database

The model builder starts from a deterministic WSD seed exported from the validated cTAKES dictionary. It then scans the selected UMLS 2026AA sources only for CUIs that can actually appear in that dictionary.

Model contentAccepted build count
Candidate profiles293,770
Dictionary terms468,335
Ranked UMLS terms832,876
Definitions11,631
Directed relation edges73,238
Ambiguous CUIs represented2,347

The term-free build receipt records settings, counts, source identifiers, file hashes, dictionary database hash, and source-release rows. The model itself remains licensed terminology-derived data and is not committed to the public repository.

06

A default-on run fails before Java when the WSD assets do not match

The runtime resolves an explicit CLI model first, then environment configuration, then the active dictionary release’s controlled model path. It does not silently fall back to WSD off.

  1. Hash the complete SQLite model.
  2. Read the term-free build receipt and compare its recorded model hash.
  3. Compare dictionary release, UMLS release, dictionary ID, and dictionary database hash with the selected strict dictionary manifest.
  4. Open the SQLite model read-only and run quick_check.
  5. Require the expected schema, completed-build marker, and non-empty profile table.
  6. Write wsd_validation.json and bind its hash into the run manifest and SQLite metadata.

The generated effective piper records the WSD profile ID, context limits, thresholds, temperature, and weights. That means a setting change alters the normalized pipeline hash and therefore the analysis_id.

Read the gate: scripts/validate_wsd_model.py validates the model before Java, and scripts/check_run.py checks the completed WSD rows.

Run an explicit WSD-off comparison
bash scripts/run_pipeline.sh \
  --input /approved/usdhub/batch \
  --output /approved/usdhub/results-wsd-off \
  --no-wsd
07

Startup reuses a completed model validation without weakening the Java check

Before Java starts, the wrapper hashes the complete WSD model, matches its build receipt and dictionary binding, opens SQLite, and runs quick_check. It passes the validated real path and SHA-256 into Java so the annotator does not repeat the same full database scan.

StageCurrent requirement
Wrapper preflightFull model hash, build receipt, dictionary binding, SQLite quick_check, schema, completion marker, and profile count.
Java reuse conditionThe wrapper-validation flag, resolved model path, and complete SHA-256 must all match.
Java checks that still runExpected schema, completed-build marker, and a non-empty profile table.
Standalone or mismatched useThe annotator performs the full validation path instead of trusting a partial signal.

This removes duplicate startup work only when the wrapper and Java agree on the exact model bytes. It does not turn off model validation.

See where WSD validation sits inside the complete startup lifecycle.

08

Default-on engineering behavior and clinical validation remain separate

The current wrapper 2.1 direct fixture contained 13 ambiguous mentions. The model abstained on all 13, so that execution did not force a winner when the configured evidence gates were not satisfied. The separate synthetic fixture produced one winner row, one loser row, and six blank singleton rows, which checks the decision path without treating a synthetic phrase as clinical validation.

A clinical review needs an ambiguity gold set sampled from the intended notes, candidate-level adjudication, accuracy/coverage for decisions, abstention rate, error analysis by semantic type and source vocabulary, and a locked evaluation set that was not used to tune thresholds.