aimedicalcoding 0.3.1__tar.gz → 0.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aimedicalcoding-0.3.1/aimedicalcoding.egg-info → aimedicalcoding-0.3.4}/PKG-INFO +2 -2
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/README.md +15 -6
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/README_PYPI.md +1 -1
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/serialize.py +24 -14
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/patterns.py +13 -2
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4/aimedicalcoding.egg-info}/PKG-INFO +2 -2
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/GAP_SCHEMA.md +8 -5
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/setup.py +1 -1
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/LICENSE +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/MANIFEST.in +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/__main__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/base.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/ccda/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/ccda/adapter.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/ccda/codes.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/ccda/narrative.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/ccda/sections.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/custom_json/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/custom_json/adapter.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/fhir/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/fhir/adapter.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/fhir/codes.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/fhir/mapping.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/api.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/core/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/core/checkdigits.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/core/models.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/core/system_registry.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/pipeline/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/pipeline/orchestrator.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/recovery/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/recovery/engine.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/base.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/cvx/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/cvx/handler.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/cvx/normalize.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/cvx/patterns.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/icd10cm/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/icd10cm/handler.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/icd10cm/icdformat.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/icd10cm/patterns.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/loinc/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/loinc/axes.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/loinc/handler.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/loinc/normalize.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/loinc/patterns.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/rxnorm/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/rxnorm/handler.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/rxnorm/normalize.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/rxnorm/patterns.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/handler.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/hierarchy.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/qualifiers.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/terminology/__init__.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/terminology/service.py +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/SOURCES.txt +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/dependency_links.txt +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/entry_points.txt +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/requires.txt +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/top_level.txt +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/ARCHITECTURE.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/OUTPUT_GUIDE.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/patterns/CVX_pattern_analysis.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/patterns/ICD10CM_pattern_analysis.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/patterns/LOINC_pattern_analysis.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/patterns/RxNorm_pattern_analysis.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/docs/patterns/SNOMED_pattern_analysis.md +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/pyproject.toml +0 -0
- {aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aimedicalcoding
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Detect missing/broken clinical codes (LOINC / SNOMED CT / RxNorm / ICD-10-CM / CVX) in CCDA and FHIR documents, with recovery evidence
|
|
5
5
|
Author: Aakash Kag, Vinay Shankar Miryala, Siva Karthik, Mohammed Rayaan
|
|
6
6
|
License: MIT
|
|
@@ -194,7 +194,7 @@ to fix it:
|
|
|
194
194
|
| `ICD_ONLY` | ICD present, SNOMED missing | official ICD ↔ SNOMED map |
|
|
195
195
|
| `SNOMED_ONLY` | SNOMED present, ICD-10-CM missing | official SNOMED → ICD-10-CM map |
|
|
196
196
|
| `NDC_ONLY` | NDC present, RxNorm/CVX missing | NDC ↔ RxNorm / CDC NDC ↔ CVX table |
|
|
197
|
-
| `RXNORM_ONLY` | RxNorm vaccine
|
|
197
|
+
| `RXNORM_ONLY` | RxNorm present, target missing (vaccine → CVX; drug allergen → SNOMED) | CVX ↔ RxNorm map / RxNorm ↔ SNOMED via UMLS |
|
|
198
198
|
| `MULTUM_ONLY` / `FDB_ONLY` / `MEDISPAN_ONLY` | proprietary drug vocabulary, RxNorm missing | vendor ↔ RxNorm via UMLS |
|
|
199
199
|
|
|
200
200
|
---
|
|
@@ -56,11 +56,20 @@ Run tests:
|
|
|
56
56
|
```bash
|
|
57
57
|
pytest
|
|
58
58
|
```
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
59
|
+
|
|
60
|
+
### Publish to PyPI
|
|
61
|
+
|
|
62
|
+
See **`PUBLISHING.md`** for the full release guide (version bump in `setup.py`,
|
|
63
|
+
clean build, `twine check`, upload, verify, troubleshooting). Short version:
|
|
64
|
+
|
|
65
|
+
```powershell
|
|
66
|
+
# bump version in setup.py first — PyPI rejects re-uploads of the same version
|
|
67
|
+
Remove-Item -Recurse -Force dist; python -m build
|
|
68
|
+
python -m twine check dist/*
|
|
69
|
+
python -m twine upload dist/* # credentials from ~/.pypirc
|
|
62
70
|
```
|
|
63
|
-
|
|
71
|
+
|
|
72
|
+
Alternative: private publish to AWS CodeArtifact (the repo is on CodeCommit):
|
|
64
73
|
```bash
|
|
65
74
|
aws codeartifact login --tool twine --domain <domain> --repository <repo>
|
|
66
75
|
twine upload --repository codeartifact dist/*
|
|
@@ -187,7 +196,7 @@ a FHIR Bundle, and which gap patterns each can produce:
|
|
|
187
196
|
| Target | CCDA source (slot) | FHIR source (slot) | Gap patterns it can emit |
|
|
188
197
|
|---|---|---|---|
|
|
189
198
|
| **LOINC** | results / vitals / surveys — observation `code` (question) | `Observation.code` (category `laboratory`/`vital-signs`/`social-history`/`survey`) | `LOCAL_CODE_ONLY` · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` · `BAD_CODE` |
|
|
190
|
-
| **SNOMED CT** | problems / family hx / social hx / reactions — `value`; procedures / allergen substance — `code` | `Condition.code` / `FamilyMemberHistory.condition[].code` / `Observation.valueCodeableConcept` / `reaction[].manifestation[]` — value slot; `Procedure.code` / `AllergyIntolerance.code` — code slot | `LOCAL_CODE_ONLY` · **`ICD_ONLY`** · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` · `BAD_CODE` |
|
|
199
|
+
| **SNOMED CT** | problems / family hx / social hx / reactions — `value`; procedures / allergen substance — `code` | `Condition.code` / `FamilyMemberHistory.condition[].code` / `Observation.valueCodeableConcept` / `reaction[].manifestation[]` — value slot; `Procedure.code` / `AllergyIntolerance.code` — code slot | `LOCAL_CODE_ONLY` · **`ICD_ONLY`** · **`RXNORM_ONLY`** · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` · `BAD_CODE` |
|
|
191
200
|
| **RxNorm** | medications — `manufacturedMaterial/code` | `Medication.code` via `medicationReference` (or inline `medicationCodeableConcept`) | **`NDC_ONLY`** · **`MULTUM_ONLY`** · **`FDB_ONLY`** · **`MEDISPAN_ONLY`** · `LOCAL_CODE_ONLY` · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` |
|
|
192
201
|
| **ICD-10-CM** | problems / encounters — diagnosis `value` | `Condition.code` (value slot) | **`SNOMED_ONLY`** · `LOCAL_CODE_ONLY` · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` · `BAD_CODE` |
|
|
193
202
|
| **CVX** | immunizations — `manufacturedMaterial/code` | `Immunization.vaccineCode` | **`RXNORM_ONLY`** · **`NDC_ONLY`** · `LOCAL_CODE_ONLY` · `NULLFLAVOR` · `DISPLAY_ONLY` · `NARRATIVE_ONLY` · `BAD_CODE` |
|
|
@@ -217,7 +226,7 @@ deterministically to the target. Full schema + per-pattern JSON in
|
|
|
217
226
|
| `ICD_ONLY` | ICD-9/10 present, no SNOMED | ICD↔SNOMED map (NLM) |
|
|
218
227
|
| `SNOMED_ONLY` | SNOMED present, no ICD-10-CM | SNOMED→ICD-10-CM map (NLM) |
|
|
219
228
|
| `NDC_ONLY` | NDC present, no RxNorm/CVX | NDC↔RxNorm / CDC NDC↔CVX table |
|
|
220
|
-
| `RXNORM_ONLY` | RxNorm
|
|
229
|
+
| `RXNORM_ONLY` | RxNorm code present, target missing (vaccine → CVX; drug allergen → SNOMED) | CVX↔RxNorm map / RxNorm↔SNOMED via UMLS |
|
|
221
230
|
| `MULTUM_ONLY` / `FDB_ONLY` / `MEDISPAN_ONLY` | proprietary drug vocab, no RxNorm | vendor↔RxNorm via UMLS CUI |
|
|
222
231
|
|
|
223
232
|
Skipped (never emitted): a valid code for the target (incl. via `<translation>`),
|
|
@@ -157,7 +157,7 @@ to fix it:
|
|
|
157
157
|
| `ICD_ONLY` | ICD present, SNOMED missing | official ICD ↔ SNOMED map |
|
|
158
158
|
| `SNOMED_ONLY` | SNOMED present, ICD-10-CM missing | official SNOMED → ICD-10-CM map |
|
|
159
159
|
| `NDC_ONLY` | NDC present, RxNorm/CVX missing | NDC ↔ RxNorm / CDC NDC ↔ CVX table |
|
|
160
|
-
| `RXNORM_ONLY` | RxNorm vaccine
|
|
160
|
+
| `RXNORM_ONLY` | RxNorm present, target missing (vaccine → CVX; drug allergen → SNOMED) | CVX ↔ RxNorm map / RxNorm ↔ SNOMED via UMLS |
|
|
161
161
|
| `MULTUM_ONLY` / `FDB_ONLY` / `MEDISPAN_ONLY` | proprietary drug vocabulary, RxNorm missing | vendor ↔ RxNorm via UMLS |
|
|
162
162
|
|
|
163
163
|
---
|
|
@@ -121,13 +121,18 @@ def _dedupe(items) -> list:
|
|
|
121
121
|
return out
|
|
122
122
|
|
|
123
123
|
|
|
124
|
-
# SNOMED search-term enrichment
|
|
125
|
-
#
|
|
126
|
-
#
|
|
127
|
-
#
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
# SNOMED search-term enrichment (Problems 11450-4, Allergies 48765-2, Social
|
|
125
|
+
# History 29762-2), matched by section LOINC or by the contexts those sections
|
|
126
|
+
# route to (FHIR resources often carry no meta.tag/section code). Which slot's
|
|
127
|
+
# labels get appended differs by section:
|
|
128
|
+
# - Social History -> CODE tag labels (the question, e.g. "Gender identity" —
|
|
129
|
+
# the value label is often a placeholder like "Not on file")
|
|
130
|
+
# - Problems / Allergies -> VALUE tag labels (the concept; the code tag is a
|
|
131
|
+
# generic marker like ASSERTION / "Problem" — appending it is noise)
|
|
132
|
+
_SNOMED_CODE_LABEL_SECTIONS = {"29762-2"}
|
|
133
|
+
_SNOMED_CODE_LABEL_CONTEXTS = {"social_history"}
|
|
134
|
+
_SNOMED_VALUE_LABEL_SECTIONS = {"11450-4", "48765-2"}
|
|
135
|
+
_SNOMED_VALUE_LABEL_CONTEXTS = {"problem", "allergy_substance", "allergy_reaction"}
|
|
131
136
|
|
|
132
137
|
|
|
133
138
|
def _recovery(record: NormalizedRecord, slot: str, system: str) -> dict:
|
|
@@ -141,13 +146,18 @@ def _recovery(record: NormalizedRecord, slot: str, system: str) -> dict:
|
|
|
141
146
|
terms = [stmt.display_name, stmt.original_text]
|
|
142
147
|
# add any normalized term the handler produced
|
|
143
148
|
terms += [ev.get("analyte_normalized"), ev.get("term_normalized"), ev.get("ingredient")]
|
|
144
|
-
# SNOMED only, Problems/Allergies/Social History only: append
|
|
145
|
-
#
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
149
|
+
# SNOMED only, Problems/Allergies/Social History only: append trailing
|
|
150
|
+
# label context from the section-appropriate slot (see constants above).
|
|
151
|
+
if system == System.SNOMEDCT.value:
|
|
152
|
+
if (stmt.section_code in _SNOMED_CODE_LABEL_SECTIONS
|
|
153
|
+
or stmt.context in _SNOMED_CODE_LABEL_CONTEXTS):
|
|
154
|
+
terms += [stmt.display_name, stmt.original_text]
|
|
155
|
+
elif (stmt.section_code in _SNOMED_VALUE_LABEL_SECTIONS
|
|
156
|
+
or stmt.context in _SNOMED_VALUE_LABEL_CONTEXTS):
|
|
157
|
+
if stmt.value:
|
|
158
|
+
terms += [stmt.value.coded_value.display
|
|
159
|
+
if stmt.value.coded_value else None,
|
|
160
|
+
stmt.value.original_text]
|
|
151
161
|
|
|
152
162
|
rec = {
|
|
153
163
|
"search_terms": _dedupe(terms),
|
|
@@ -31,6 +31,7 @@ ICD_SYSTEMS = {System.ICD10CM, System.ICD9CM, System.ICD10PCS}
|
|
|
31
31
|
class SnomedGapPattern(str, Enum):
|
|
32
32
|
LOCAL_CODE_ONLY = "LOCAL_CODE_ONLY" # a local/other clinical code (incl. CPT), no SNOMED
|
|
33
33
|
ICD_ONLY = "ICD_ONLY" # ICD-9/10 only -> ICD↔SNOMED crosswalk
|
|
34
|
+
RXNORM_ONLY = "RXNORM_ONLY" # RxNorm-coded allergen -> RxNorm↔SNOMED (UMLS)
|
|
34
35
|
NULLFLAVOR = "NULLFLAVOR"
|
|
35
36
|
DISPLAY_ONLY = "DISPLAY_ONLY"
|
|
36
37
|
NARRATIVE_ONLY = "NARRATIVE_ONLY"
|
|
@@ -107,13 +108,17 @@ def classify(stmt: ClinicalStatement) -> Optional[SnomedGapPattern]:
|
|
|
107
108
|
|
|
108
109
|
if cc and cc.code and cc.system in ICD_SYSTEMS:
|
|
109
110
|
return SnomedGapPattern.ICD_ONLY
|
|
111
|
+
if cc and cc.code and cc.system == System.RXNORM:
|
|
112
|
+
return SnomedGapPattern.RXNORM_ONLY # standard vocab, not "local"
|
|
110
113
|
if cc and cc.code and cc.system not in STRUCTURAL:
|
|
111
114
|
return SnomedGapPattern.LOCAL_CODE_ONLY # CPT / local / other
|
|
112
115
|
|
|
113
|
-
# no usable concept code
|
|
116
|
+
# no usable concept code. The label must come from the CONCEPT's slot
|
|
117
|
+
# (value display/originalText for value-slot contexts) — raw_text alone
|
|
118
|
+
# misses e.g. reaction observations whose code tag is a bare ASSERTION.
|
|
114
119
|
if _has_nullflavor(stmt):
|
|
115
120
|
return SnomedGapPattern.NULLFLAVOR
|
|
116
|
-
if stmt
|
|
121
|
+
if concept_term(stmt):
|
|
117
122
|
if "/text" in (stmt.source_ref or ""):
|
|
118
123
|
return SnomedGapPattern.NARRATIVE_ONLY
|
|
119
124
|
return SnomedGapPattern.DISPLAY_ONLY
|
|
@@ -152,6 +157,12 @@ def parse_gap(stmt: ClinicalStatement, pattern: SnomedGapPattern) -> Gap:
|
|
|
152
157
|
gap.evidence["icd_system"] = (cc.system.value if cc.system else None)
|
|
153
158
|
gap.note = ("Use the official ICD↔SNOMED map (NLM/UMLS) — deterministic; "
|
|
154
159
|
"LLM only to choose among multiple map targets.")
|
|
160
|
+
elif pattern == SnomedGapPattern.RXNORM_ONLY and cc:
|
|
161
|
+
gap.evidence["rxnorm_code"] = cc.code
|
|
162
|
+
gap.evidence["rxnorm_system"] = cc.raw_system
|
|
163
|
+
gap.note = ("RxNorm-coded allergen (drug allergy) — crosswalk RxNorm → "
|
|
164
|
+
"SNOMED substance/product via UMLS CUI; LLM only if the "
|
|
165
|
+
"ingredient maps ambiguously.")
|
|
155
166
|
elif pattern == SnomedGapPattern.BAD_CODE and cc:
|
|
156
167
|
gap.evidence["malformed_code"] = cc.code
|
|
157
168
|
gap.note = "SCTID-shaped but Verhoeff check failed; resolve via text + hierarchy."
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aimedicalcoding
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Detect missing/broken clinical codes (LOINC / SNOMED CT / RxNorm / ICD-10-CM / CVX) in CCDA and FHIR documents, with recovery evidence
|
|
5
5
|
Author: Aakash Kag, Vinay Shankar Miryala, Siva Karthik, Mohammed Rayaan
|
|
6
6
|
License: MIT
|
|
@@ -194,7 +194,7 @@ to fix it:
|
|
|
194
194
|
| `ICD_ONLY` | ICD present, SNOMED missing | official ICD ↔ SNOMED map |
|
|
195
195
|
| `SNOMED_ONLY` | SNOMED present, ICD-10-CM missing | official SNOMED → ICD-10-CM map |
|
|
196
196
|
| `NDC_ONLY` | NDC present, RxNorm/CVX missing | NDC ↔ RxNorm / CDC NDC ↔ CVX table |
|
|
197
|
-
| `RXNORM_ONLY` | RxNorm vaccine
|
|
197
|
+
| `RXNORM_ONLY` | RxNorm present, target missing (vaccine → CVX; drug allergen → SNOMED) | CVX ↔ RxNorm map / RxNorm ↔ SNOMED via UMLS |
|
|
198
198
|
| `MULTUM_ONLY` / `FDB_ONLY` / `MEDISPAN_ONLY` | proprietary drug vocabulary, RxNorm missing | vendor ↔ RxNorm via UMLS |
|
|
199
199
|
|
|
200
200
|
---
|
|
@@ -40,7 +40,7 @@ Each record separates four concerns:
|
|
|
40
40
|
| `id` | sequence number |
|
|
41
41
|
| `target.system` | `LOINC` \| `SNOMED-CT` — which terminology this gap recovers |
|
|
42
42
|
| `target.slot` | `code` (question/analyte) \| `value` (answer) — which slot is being filled |
|
|
43
|
-
| `pattern` | `LOCAL_CODE_ONLY` \| `ICD_ONLY` \| `NULLFLAVOR` \| `DISPLAY_ONLY` \| `BAD_CODE` \| `NARRATIVE_ONLY` |
|
|
43
|
+
| `pattern` | `LOCAL_CODE_ONLY` \| `ICD_ONLY` \| `RXNORM_ONLY` \| `NULLFLAVOR` \| `DISPLAY_ONLY` \| `BAD_CODE` \| `NARRATIVE_ONLY` |
|
|
44
44
|
| `payload_type` | `codeable` (code is the concept, value is a measurement) \| `qa` (code is a question, value is a coded answer) |
|
|
45
45
|
| `section` | `{ code, name, system }` — the source section |
|
|
46
46
|
| **`observation`** | the faithful facts of BOTH slots (see below) |
|
|
@@ -89,10 +89,12 @@ Each record separates four concerns:
|
|
|
89
89
|
- `target.slot = "code"` (LOINC) → search `observation.code.display_text` / `.original_text`.
|
|
90
90
|
- `target.slot = "value"` (SNOMED value-slot) → search `observation.value.display_text` / `.original_text`.
|
|
91
91
|
`recovery.search_terms` already gives you the right ones, deduped.
|
|
92
|
-
For **SNOMED-CT** targets
|
|
93
|
-
Social History (29762-2)
|
|
94
|
-
|
|
95
|
-
|
|
92
|
+
For **SNOMED-CT** targets, extra label context is appended at the end,
|
|
93
|
+
section-specific: **Social History (29762-2)** appends the CODE tag's
|
|
94
|
+
`display_text`/`original_text` (the question — useful when the value label
|
|
95
|
+
is a placeholder like "Not on file"); **Problems (11450-4)** and
|
|
96
|
+
**Allergies (48765-2)** append the VALUE tag's labels (the concept — the
|
|
97
|
+
code tag there is a generic marker like ASSERTION/"Problem").
|
|
96
98
|
|
|
97
99
|
---
|
|
98
100
|
|
|
@@ -102,6 +104,7 @@ for when the value label is a placeholder like "Not on file".
|
|
|
102
104
|
|---|---|---|---|
|
|
103
105
|
| `LOCAL_CODE_ONLY` | both | a local/in-house code (or CPT for SNOMED proc), no target code | crosswalk first, else text+filter |
|
|
104
106
|
| `ICD_ONLY` | SNOMED | value coded in ICD-9/10 only | **ICD↔SNOMED map** (deterministic) |
|
|
107
|
+
| `RXNORM_ONLY` | SNOMED | allergen coded in RxNorm only (drug allergy) | **RxNorm↔SNOMED via UMLS CUI** |
|
|
105
108
|
| `NULLFLAVOR` | both | code blank; label recovered from narrative | text+filter on search_terms |
|
|
106
109
|
| `DISPLAY_ONLY` | both | a display/text but no usable code | text+filter |
|
|
107
110
|
| `BAD_CODE` | both | shaped right, check digit fails (Luhn/Verhoeff) | LOINC: `checkdigit_correction`; SNOMED: re-resolve |
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="aimedicalcoding",
|
|
5
|
-
version="0.3.
|
|
5
|
+
version="0.3.4",
|
|
6
6
|
author="Aakash Kag, Vinay Shankar Miryala, Siva Karthik, Mohammed Rayaan",
|
|
7
7
|
description=(
|
|
8
8
|
"Detect missing/broken clinical codes (LOINC / SNOMED CT / RxNorm / "
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/custom_json/__init__.py
RENAMED
|
File without changes
|
{aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/adapters/custom_json/adapter.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/icd10cm/icdformat.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding/systems/snomed/qualifiers.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aimedicalcoding-0.3.1 → aimedicalcoding-0.3.4}/aimedicalcoding.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|