File size: 3,262 Bytes
4b988e0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
"""UMLS semantic type (TUI) codes and definitions (embedded)."""

import re

_TUI_SPLIT = re.compile(r"[;|,/\s]+")

TUI_DEFINITIONS: dict[str, str] = {
    "T004": "Fungus",
    "T005": "Virus",
    "T007": "Bacterium",
    "T017": "Anatomical Structure",
    "T019": "Congenital Abnormality",
    "T021": "Fully Formed Anatomical Structure",
    "T022": "Body System",
    "T023": "Body Part, Organ, or Organ Component",
    "T024": "Tissue",
    "T025": "Cell",
    "T026": "Cell Component",
    "T028": "Gene or Genome",
    "T029": "Body Location or Region",
    "T030": "Body Space or Junction",
    "T031": "Body Substance",
    "T032": "Organism Attribute",
    "T033": "Finding",
    "T034": "Laboratory or Test Result",
    "T037": "Injury or Poisoning",
    "T038": "Biologic Function",
    "T039": "Physiologic Function",
    "T040": "Organism Function",
    "T041": "Mental Process",
    "T042": "Organ or Tissue Function",
    "T043": "Cell Function",
    "T044": "Molecular Function",
    "T045": "Genetic Function",
    "T046": "Pathologic Function",
    "T047": "Disease or Syndrome",
    "T048": "Mental or Behavioral Dysfunction",
    "T049": "Cell or Molecular Dysfunction",
    "T050": "Experimental Model of Disease",
    "T053": "Behavior",
    "T055": "Individual Behavior",
    "T059": "Laboratory Procedure",
    "T060": "Diagnostic Procedure",
    "T061": "Therapeutic or Preventive Procedure",
    "T067": "Phenomenon or Process",
    "T074": "Medical Device",
    "T081": "Quantitative Concept",
    "T085": "Molecular Sequence",
    "T086": "Nucleotide Sequence",
    "T087": "Amino Acid Sequence",
    "T093": "Health Care Related Organization",
    "T094": "Professional Society",
    "T114": "Nucleic Acid, Nucleoside, or Nucleotide",
    "T116": "Amino Acid, Peptide, or Protein",
    "T121": "Pharmacologic Substance",
    "T123": "Biologically Active Substance",
    "T125": "Hormone",
    "T126": "Enzyme",
    "T127": "Vitamin",
    "T129": "Immunologic Factor",
    "T131": "Hazardous or Poisonous Substance",
    "T184": "Sign or Symptom",
    "T191": "Neoplastic Process",
    "T192": "Receptor",
    "T195": "Antibiotic",
    "T200": "Clinical Drug",
    "T201": "Clinical Attribute",
    "T203": "Drug Delivery Device",
}


def tui_display(code: str) -> str:
    """Return ``T047 — Disease or Syndrome`` for a single TUI code."""
    c = (code or "").strip().upper()
    if not c:
        return ""
    name = TUI_DEFINITIONS.get(c, "")
    return f"{c} — {name}" if name else c


def format_tui_list(raw: str, *, compact: bool = False) -> str:
    """Format pipe/semicolon-separated TUI codes with definitions."""
    if not raw:
        return ""
    parts = [p for p in _TUI_SPLIT.split(raw.strip()) if p.strip()]
    if not parts:
        return ""
    if compact and len(parts) == 1:
        return tui_display(parts[0])
    return "; ".join(tui_display(p) for p in parts)


def tui_codes(raw: str) -> set[str]:
    """Split a raw TUI field into individual codes."""
    if not raw:
        return set()
    out: set[str] = set()
    for part in _TUI_SPLIT.split(str(raw).strip()):
        code = part.strip().upper()
        if code.startswith("T") and len(code) >= 4:
            out.add(code)
    return out