Skip to content

Commit 51fcccd

Browse files
committed
Added DiagnosticTestHasResult mapping class and result filter criteria for diagnostic test selection
1 parent 10c9e4c commit 51fcccd

File tree

4 files changed

+97
-21
lines changed

4 files changed

+97
-21
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class DiagnosticTestHasResult:
2+
"""
3+
Maps descriptive flags and result labels to internal identifiers.
4+
Used for interpreting criteria values for diagnostic test result presence or type.
5+
"""
6+
7+
YES = "yes"
8+
NO = "no"
9+
10+
_label_to_id = {
11+
"positive": 9001,
12+
"negative": 9002,
13+
"indeterminate": 9003,
14+
# Add additional mappings as needed
15+
}
16+
17+
_valid_flags = {YES, NO}
18+
19+
@classmethod
20+
def from_description(cls, description: str):
21+
key = description.strip().lower()
22+
if key in cls._valid_flags:
23+
return key
24+
if key in cls._label_to_id:
25+
return cls._label_to_id[key]
26+
raise ValueError(f"Unknown diagnostic test result description: '{description}'")
27+
28+
@classmethod
29+
def get_id(cls, description: str) -> int:
30+
key = description.strip().lower()
31+
if key not in cls._label_to_id:
32+
raise ValueError(f"No ID available for result description: '{description}'")
33+
return cls._label_to_id[key]

utils/oracle/mock_selection_builder.py

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88

99
# Add helper class stubs below
10-
class DiagnosticTestIsVoid:
10+
class DiagnosticTestHasResult:
1111
"""
12-
Maps yes/no descriptions to boolean flags for test void criteria.
12+
Resolves whether a diagnostic test has a result, or maps to a specific result ID.
1313
"""
1414

1515
YES = "yes"
@@ -18,15 +18,25 @@ class DiagnosticTestIsVoid:
1818
_mapping = {
1919
"yes": YES,
2020
"no": NO,
21+
"positive": 9001,
22+
"negative": 9002,
23+
"indeterminate": 9003,
2124
}
2225

2326
@classmethod
24-
def from_description(cls, description: str) -> str:
27+
def from_description(cls, description: str):
2528
key = description.strip().lower()
2629
if key not in cls._mapping:
27-
raise ValueError(f"Unknown void flag: {description}")
30+
raise ValueError(f"Unknown test result description: '{description}'")
2831
return cls._mapping[key]
2932

33+
@classmethod
34+
def get_id(cls, description: str) -> int:
35+
val = cls.from_description(description)
36+
if isinstance(val, int):
37+
return val
38+
raise ValueError(f"No ID associated with: '{description}'")
39+
3040

3141
class MockSelectionBuilder:
3242
"""
@@ -75,22 +85,25 @@ def _add_join_to_latest_episode(self) -> None:
7585
# Replace this with the one you want to test,
7686
# then use utils/oracle/test_subject_criteria_dev.py to run your scenarios
7787

78-
def _add_criteria_diagnostic_test_is_void(self) -> None:
88+
def _add_criteria_diagnostic_test_has_result(self) -> None:
7989
"""
80-
Adds WHERE clause to check whether diagnostic test is voided ('Y' or 'N').
81-
Requires prior join to external_tests_t using alias xtN.
90+
Adds WHERE clause to check whether a diagnostic test has a result (IS NULL / NOT NULL / = result_id).
8291
"""
8392
try:
8493
idx = getattr(self, "criteria_index", 0)
8594
xt = f"xt{idx}"
86-
value = DiagnosticTestIsVoid.from_description(self.criteria_value)
95+
value = self.criteria_value.strip().lower()
96+
result = DiagnosticTestHasResult.from_description(value)
97+
98+
self.sql_where.append(f"AND {xt}.result_id ")
8799

88-
if value == DiagnosticTestIsVoid.YES:
89-
self.sql_where.append(f"AND {xt}.void = 'Y'")
90-
elif value == DiagnosticTestIsVoid.NO:
91-
self.sql_where.append(f"AND {xt}.void = 'N'")
100+
if result == DiagnosticTestHasResult.YES:
101+
self.sql_where.append("IS NOT NULL")
102+
elif result == DiagnosticTestHasResult.NO:
103+
self.sql_where.append("IS NULL")
92104
else:
93-
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
105+
result_id = DiagnosticTestHasResult.get_id(value)
106+
self.sql_where.append(f"= {result_id}")
94107

95108
except Exception:
96109
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)

utils/oracle/subject_selection_query_builder.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
from classes.which_diagnostic_test import WhichDiagnosticTest
3131
from classes.diagnostic_test_type import DiagnosticTestType
3232
from classes.diagnostic_test_is_void import DiagnosticTestIsVoid
33+
from classes.diagnostic_test_has_result import DiagnosticTestHasResult
3334

3435

3536
class SubjectSelectionQueryBuilder:
@@ -1747,6 +1748,29 @@ def _add_criteria_diagnostic_test_is_void(self) -> None:
17471748
except Exception:
17481749
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
17491750

1751+
def _add_criteria_diagnostic_test_has_result(self) -> None:
1752+
"""
1753+
Adds WHERE clause to check whether a diagnostic test has a result (IS NULL / NOT NULL / = result_id).
1754+
"""
1755+
try:
1756+
idx = getattr(self, "criteria_index", 0)
1757+
xt = f"xt{idx}"
1758+
value = self.criteria_value.strip().lower()
1759+
result = DiagnosticTestHasResult.from_description(value)
1760+
1761+
self.sql_where.append(f"AND {xt}.result_id ")
1762+
1763+
if result == DiagnosticTestHasResult.YES:
1764+
self.sql_where.append("IS NOT NULL")
1765+
elif result == DiagnosticTestHasResult.NO:
1766+
self.sql_where.append("IS NULL")
1767+
else:
1768+
result_id = DiagnosticTestHasResult.get_id(value)
1769+
self.sql_where.append(f"= {result_id}")
1770+
1771+
except Exception:
1772+
raise SelectionBuilderException(self.criteria_key_name, self.criteria_value)
1773+
17501774
# ------------------------------------------------------------------------
17511775
# 🧬 CADS Clinical Dataset Filters
17521776
# ------------------------------------------------------------------------

utils/oracle/test_subject_criteria_dev.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,20 @@ def make_builder(key, value, index=0):
3737
return b
3838

3939

40-
# === Test: DIAGNOSTIC_TEST_IS_VOID ===
41-
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_IS_VOID, "yes")
42-
b._add_criteria_diagnostic_test_is_void()
43-
print("=== DIAGNOSTIC_TEST_IS_VOID ===")
40+
# === Test: DIAGNOSTIC_TEST_HAS_RESULT (yes) ===
41+
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_RESULT, "yes")
42+
b._add_criteria_diagnostic_test_has_result()
43+
print("=== DIAGNOSTIC_TEST_HAS_RESULT (yes) ===")
4444
print(b.dump_sql(), end="\n\n")
4545

46-
# === Test: DIAGNOSTIC_TEST_IS_VOID (not void) ===
47-
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_IS_VOID, "no", index=1)
48-
b._add_criteria_diagnostic_test_is_void()
49-
print("=== DIAGNOSTIC_TEST_IS_VOID (not void) ===")
46+
# === Test: DIAGNOSTIC_TEST_HAS_RESULT (no) ===
47+
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_RESULT, "no")
48+
b._add_criteria_diagnostic_test_has_result()
49+
print("=== DIAGNOSTIC_TEST_HAS_RESULT (no) ===")
50+
print(b.dump_sql(), end="\n\n")
51+
52+
# === Test: DIAGNOSTIC_TEST_HAS_RESULT (positive) ===
53+
b = make_builder(SubjectSelectionCriteriaKey.DIAGNOSTIC_TEST_HAS_RESULT, "positive")
54+
b._add_criteria_diagnostic_test_has_result()
55+
print("=== DIAGNOSTIC_TEST_HAS_RESULT (positive) ===")
5056
print(b.dump_sql(), end="\n\n")

0 commit comments

Comments
 (0)