|
a |
|
b/tests/test_ontology.py |
|
|
1 |
# flake8: noqa: E501 |
|
|
2 |
|
|
|
3 |
import pathlib |
|
|
4 |
|
|
|
5 |
import femr.ontology |
|
|
6 |
|
|
|
7 |
|
|
|
8 |
def create_fake_athena(tmp_path: pathlib.Path) -> pathlib.Path: |
|
|
9 |
athena = tmp_path / "athena" |
|
|
10 |
athena.mkdir() |
|
|
11 |
|
|
|
12 |
concept = athena / "CONCEPT.csv" |
|
|
13 |
concept.write_text( |
|
|
14 |
"""concept_id concept_name domain_id vocabulary_id concept_class_id standard_concept concept_code valid_start_date valid_end_date invalid_reason |
|
|
15 |
37200198\tType 2 diabetes mellitus with mild nonproliferative diabetic retinopathy with macular edema, right eye\tCondition\tICD10CM\t7-char billing code\t\tE11.3211\t19700101\t20991231\t |
|
|
16 |
380097\tMacular edema due to diabetes mellitus\tCondition\tSNOMED\tClinical Finding\tS\t312912001\t20020131\t20991231 |
|
|
17 |
4334884 Disorder of macula due to diabetes mellitus Condition SNOMED Clinical Finding S 232020009 20020131 20991231 |
|
|
18 |
4174977 Retinopathy due to diabetes mellitus Condition SNOMED Clinical Finding S 4855003 20020131 20991231 |
|
|
19 |
4208223 Disorder of macula of retina Condition SNOMED Clinical Finding S 312999006 20020131 20991231 |
|
|
20 |
4290333 Macular retinal edema Condition SNOMED Clinical Finding S 37231002 20020131 20991231 |
|
|
21 |
35626904 Retinal edema due to diabetes mellitus Condition SNOMED Clinical Finding S 770323005 20180731 20991231 |
|
|
22 |
45757435 Mild nonproliferative retinopathy due to type 2 diabetes mellitus Condition SNOMED Clinical Finding S 138911000119106 20150131 20991231 |
|
|
23 |
""" |
|
|
24 |
) |
|
|
25 |
relationship = athena / "CONCEPT_RELATIONSHIP.csv" |
|
|
26 |
relationship.write_text( |
|
|
27 |
"""concept_id_1 concept_id_2 relationship_id valid_start_date valid_end_date invalid_reason |
|
|
28 |
37200198 380097 Maps to 20171001 20991231 |
|
|
29 |
37200198 1567956 Is a 20170428 20991231 |
|
|
30 |
37200198 1567959 Is a 20170428 20991231 |
|
|
31 |
37200198 45757435 Maps to 20171001 20991231 |
|
|
32 |
37200198 1567961 Is a 20170428 20991231 |
|
|
33 |
37200198 45552385 Is a 20170428 20991231 |
|
|
34 |
35977781 35977781 Mapped from 20200913 20991231 |
|
|
35 |
46135811 40642538 Has status 20220128 20991231 |
|
|
36 |
46135811 35631990 Has Module 20220128 20991231""" |
|
|
37 |
) |
|
|
38 |
|
|
|
39 |
ancestor = athena / "CONCEPT_ANCESTOR.csv" |
|
|
40 |
ancestor.write_text( |
|
|
41 |
"""ancestor_concept_id\tdescendant_concept_id\tmin_levels_of_separation\tmax_levels_of_separation |
|
|
42 |
373499 4334884 4 6 |
|
|
43 |
442793 4334884 3 3 |
|
|
44 |
255919 4334884 6 9 |
|
|
45 |
433128 4334884 4 4 |
|
|
46 |
4180628 4334884 6 8 |
|
|
47 |
4209989 4334884 3 3 |
|
|
48 |
441840 4334884 6 10 |
|
|
49 |
4274025 4334884 5 9 |
|
|
50 |
4082284 4334884 2 2 |
|
|
51 |
4042836 4334884 5 7 |
|
|
52 |
443767 4334884 2 2 |
|
|
53 |
4038502 4334884 5 8 |
|
|
54 |
4174977 4334884 1 1 |
|
|
55 |
4334884 4334884 0 0 |
|
|
56 |
4134440 4334884 5 7 |
|
|
57 |
4247371 4334884 5 8 |
|
|
58 |
375252 4334884 3 5 |
|
|
59 |
4027883 4334884 4 4 |
|
|
60 |
4208223 4334884 1 1 |
|
|
61 |
378416 4334884 2 2 |
|
|
62 |
4080992 4334884 4 6 |
|
|
63 |
4162092 4334884 3 3 |
|
|
64 |
255919 380097 7 10 |
|
|
65 |
433128 380097 5 5 |
|
|
66 |
442793 380097 4 4 |
|
|
67 |
373499 380097 5 7 |
|
|
68 |
4180628 380097 7 9 |
|
|
69 |
4209989 380097 4 4 |
|
|
70 |
37018677 380097 3 3 |
|
|
71 |
441840 380097 5 11 |
|
|
72 |
380097 380097 0 0 |
|
|
73 |
4274025 380097 4 10 |
|
|
74 |
372903 380097 2 2 |
|
|
75 |
433595 380097 4 4 |
|
|
76 |
4042836 380097 6 8 |
|
|
77 |
4082284 380097 3 3 |
|
|
78 |
443767 380097 3 3 |
|
|
79 |
4038502 380097 6 9 |
|
|
80 |
4174977 380097 2 2 |
|
|
81 |
4334884 380097 1 1 |
|
|
82 |
4134440 380097 6 8 |
|
|
83 |
4247371 380097 6 9 |
|
|
84 |
4290333 380097 1 1 |
|
|
85 |
375252 380097 4 6 |
|
|
86 |
4027883 380097 5 5 |
|
|
87 |
4040388 380097 3 3 |
|
|
88 |
4208223 380097 2 2 |
|
|
89 |
35626904 380097 1 1 |
|
|
90 |
378416 380097 3 3 |
|
|
91 |
4080992 380097 5 7 |
|
|
92 |
4162092 380097 4 4 |
|
|
93 |
""" |
|
|
94 |
) |
|
|
95 |
|
|
|
96 |
return athena |
|
|
97 |
|
|
|
98 |
|
|
|
99 |
def test_only_athena(tmp_path: pathlib.Path) -> None: |
|
|
100 |
fake_athena = create_fake_athena(tmp_path) |
|
|
101 |
|
|
|
102 |
ontology = femr.ontology.Ontology(str(fake_athena)) |
|
|
103 |
|
|
|
104 |
assert ( |
|
|
105 |
ontology.get_description("ICD10CM/E11.3211") |
|
|
106 |
== "Type 2 diabetes mellitus with mild nonproliferative diabetic retinopathy with macular edema, right eye" |
|
|
107 |
) |
|
|
108 |
|
|
|
109 |
assert ontology.get_parents("ICD10CM/E11.3211") == {"SNOMED/312912001", "SNOMED/138911000119106"} |
|
|
110 |
assert ontology.get_parents("SNOMED/312912001") == {"SNOMED/37231002", "SNOMED/232020009", "SNOMED/770323005"} |
|
|
111 |
|
|
|
112 |
assert ontology.get_all_parents("ICD10CM/E11.3211") == { |
|
|
113 |
"SNOMED/37231002", |
|
|
114 |
"SNOMED/138911000119106", |
|
|
115 |
"SNOMED/4855003", |
|
|
116 |
"SNOMED/312999006", |
|
|
117 |
"SNOMED/312912001", |
|
|
118 |
"ICD10CM/E11.3211", |
|
|
119 |
"SNOMED/770323005", |
|
|
120 |
"SNOMED/232020009", |
|
|
121 |
} |
|
|
122 |
|
|
|
123 |
assert ontology.get_children("SNOMED/312912001") == {"ICD10CM/E11.3211"} |
|
|
124 |
assert ontology.get_children("SNOMED/37231002") == {"SNOMED/312912001"} |
|
|
125 |
|
|
|
126 |
assert ontology.get_all_children("SNOMED/37231002") == {"ICD10CM/E11.3211", "SNOMED/312912001", "SNOMED/37231002"} |
|
|
127 |
|
|
|
128 |
|
|
|
129 |
def test_athena_and_custom(tmp_path: pathlib.Path) -> None: |
|
|
130 |
fake_athena = create_fake_athena(tmp_path) |
|
|
131 |
|
|
|
132 |
code_metadata = { |
|
|
133 |
"CUSTOM/CustomDiabetes": {"description": "A nice diabetes code", "parent_codes": ["ICD10CM/E11.3211"]} |
|
|
134 |
} |
|
|
135 |
|
|
|
136 |
ontology = femr.ontology.Ontology(str(fake_athena), code_metadata) |
|
|
137 |
|
|
|
138 |
assert ontology.get_description("CUSTOM/CustomDiabetes") == "A nice diabetes code" |
|
|
139 |
assert ontology.get_all_parents("CUSTOM/CustomDiabetes") == { |
|
|
140 |
"CUSTOM/CustomDiabetes", |
|
|
141 |
"SNOMED/37231002", |
|
|
142 |
"SNOMED/138911000119106", |
|
|
143 |
"SNOMED/4855003", |
|
|
144 |
"SNOMED/312999006", |
|
|
145 |
"SNOMED/312912001", |
|
|
146 |
"ICD10CM/E11.3211", |
|
|
147 |
"SNOMED/770323005", |
|
|
148 |
"SNOMED/232020009", |
|
|
149 |
} |
|
|
150 |
|
|
|
151 |
assert ontology.get_all_children("SNOMED/37231002") == { |
|
|
152 |
"CUSTOM/CustomDiabetes", |
|
|
153 |
"ICD10CM/E11.3211", |
|
|
154 |
"SNOMED/312912001", |
|
|
155 |
"SNOMED/37231002", |
|
|
156 |
} |