33from pathlib import Path
44
55from pyhealth .datasets import MIMIC4Dataset
6- from pyhealth .tasks .dka import DKAPredictionMIMIC4
6+ from pyhealth .tasks .dka import DKAPredictionMIMIC4 , T1DDKAPredictionMIMIC4
77
88
99class TestMIMIC4DKAPrediction (unittest .TestCase ):
@@ -17,7 +17,7 @@ def setUp(self):
1717 def _setup_dataset_path (self ):
1818 """Get path to local MIMIC-IV demo dataset in test resources."""
1919 # Get the path to the test-resources/core/mimic4demo directory
20- test_dir = Path (__file__ ).parent .parent
20+ test_dir = Path (__file__ ).parent .parent . parent
2121 self .demo_dataset_path = str (
2222 test_dir / "test-resources" / "core" / "mimic4demo"
2323 )
@@ -26,12 +26,6 @@ def _setup_dataset_path(self):
2626 print (f"Setting up MIMIC-IV demo dataset for DKA prediction" )
2727 print (f"Dataset path: { self .demo_dataset_path } " )
2828
29- # Verify the dataset exists
30- if not os .path .exists (self .demo_dataset_path ):
31- raise unittest .SkipTest (
32- f"MIMIC-IV demo dataset not found at { self .demo_dataset_path } "
33- )
34-
3529 # List files in the hosp directory
3630 hosp_path = os .path .join (self .demo_dataset_path , "hosp" )
3731 if os .path .exists (hosp_path ):
@@ -47,9 +41,9 @@ def _load_dataset(self):
4741 """Load the dataset for testing."""
4842 tables = ["diagnoses_icd" , "procedures_icd" , "prescriptions" , "labevents" ]
4943 print (f"Loading MIMIC4Dataset with tables: { tables } " )
50- self .dataset = MIMIC4Dataset (root = self .demo_dataset_path , tables = tables )
44+ self .dataset = MIMIC4Dataset (ehr_root = self .demo_dataset_path , ehr_tables = tables )
5145 print (f"✓ Dataset loaded successfully" )
52- print (f" Total patients: { len (self .dataset .patients )} " )
46+ print (f" Total patients: { len (self .dataset .unique_patient_ids )} " )
5347 print ()
5448
5549 def test_dataset_stats (self ):
@@ -75,9 +69,33 @@ def test_dka_prediction_task_initialization(self):
7569 print ("Testing default initialization..." )
7670 task = DKAPredictionMIMIC4 ()
7771 self .assertEqual (task .task_name , "DKAPredictionMIMIC4" )
72+ self .assertEqual (task .padding , 0 )
73+ self .assertIn ("icd_codes" , task .input_schema )
74+ self .assertIn ("labs" , task .input_schema )
75+ self .assertIn ("label" , task .output_schema )
76+ print (f"✓ Default task initialized: { task .task_name } " )
77+ print (f" Input schema: { list (task .input_schema .keys ())} " )
78+ print (f" Output schema: { list (task .output_schema .keys ())} " )
79+
80+ # Test custom initialization
81+ print ("\n Testing custom initialization..." )
82+ custom_task = DKAPredictionMIMIC4 (padding = 5 )
83+ self .assertEqual (custom_task .padding , 5 )
84+ print (f"✓ Custom task initialized with padding={ custom_task .padding } " )
85+
86+ def test_t1ddka_prediction_task_initialization (self ):
87+ """Test T1DDKAPredictionMIMIC4 task initialization."""
88+ print (f"\n { '=' * 60 } " )
89+ print ("TEST: test_t1ddka_prediction_task_initialization()" )
90+ print (f"{ '=' * 60 } " )
91+
92+ # Test default initialization
93+ print ("Testing default initialization..." )
94+ task = T1DDKAPredictionMIMIC4 ()
95+ self .assertEqual (task .task_name , "T1DDKAPredictionMIMIC4" )
7896 self .assertEqual (task .dka_window_days , 90 )
7997 self .assertEqual (task .padding , 0 )
80- self .assertIn ("diagnoses " , task .input_schema )
98+ self .assertIn ("icd_codes " , task .input_schema )
8199 self .assertIn ("labs" , task .input_schema )
82100 self .assertIn ("label" , task .output_schema )
83101 print (f"✓ Default task initialized: { task .task_name } " )
@@ -87,7 +105,7 @@ def test_dka_prediction_task_initialization(self):
87105
88106 # Test custom initialization
89107 print ("\n Testing custom initialization..." )
90- custom_task = DKAPredictionMIMIC4 (dka_window_days = 30 , padding = 5 )
108+ custom_task = T1DDKAPredictionMIMIC4 (dka_window_days = 30 , padding = 5 )
91109 self .assertEqual (custom_task .dka_window_days , 30 )
92110 self .assertEqual (custom_task .padding , 5 )
93111 print (f"✓ Custom task initialized with window={ custom_task .dka_window_days } , padding={ custom_task .padding } " )
@@ -98,24 +116,37 @@ def test_dka_prediction_class_variables(self):
98116 print ("TEST: test_dka_prediction_class_variables()" )
99117 print (f"{ '=' * 60 } " )
100118
101- # Test T1DM codes
102- self .assertEqual (DKAPredictionMIMIC4 .T1DM_ICD10_PREFIX , "E10" )
103- self .assertIn ("25001" , DKAPredictionMIMIC4 .T1DM_ICD9_CODES )
104- print (f"✓ T1DM ICD-10 prefix: { DKAPredictionMIMIC4 .T1DM_ICD10_PREFIX } " )
105- print (f"✓ T1DM ICD-9 codes: { len (DKAPredictionMIMIC4 .T1DM_ICD9_CODES )} codes" )
106-
107119 # Test DKA codes
108- self .assertEqual ( DKAPredictionMIMIC4 . DKA_ICD10_PREFIX , "E101" )
120+ self .assertIn ( "E101" , DKAPredictionMIMIC4 . DKA_ICD10_PREFIXES )
109121 self .assertIn ("25011" , DKAPredictionMIMIC4 .DKA_ICD9_CODES )
110- print (f"✓ DKA ICD-10 prefix: { DKAPredictionMIMIC4 .DKA_ICD10_PREFIX } " )
122+ print (f"✓ DKA ICD-10 prefix: { DKAPredictionMIMIC4 .DKA_ICD10_PREFIXES } " )
111123 print (f"✓ DKA ICD-9 codes: { len (DKAPredictionMIMIC4 .DKA_ICD9_CODES )} codes" )
112124
113125 # Test lab categories
114- self .assertEqual (len (DKAPredictionMIMIC4 .LAB_CATEGORY_ORDER ), 6 )
115- expected_categories = ["glucose " , "bicarbonate " , "anion_gap " , "potassium " , "sodium " , "chloride " ]
126+ self .assertEqual (len (DKAPredictionMIMIC4 .LAB_CATEGORY_ORDER ), 10 )
127+ expected_categories = ["Sodium " , "Potassium " , "Chloride " , "Bicarbonate " , "Glucose " , "Calcium" , "Magnesium" , "Anion Gap" , "Osmolality" , "Phosphate " ]
116128 self .assertEqual (DKAPredictionMIMIC4 .LAB_CATEGORY_ORDER , expected_categories )
117129 print (f"✓ Lab categories: { DKAPredictionMIMIC4 .LAB_CATEGORY_ORDER } " )
118- print (f"✓ Total lab item IDs: { len (DKAPredictionMIMIC4 .ALL_LAB_ITEMIDS )} " )
130+ print (f"✓ Total lab item IDs: { len (DKAPredictionMIMIC4 .LABITEMS )} " )
131+
132+ def test_t1ddka_prediction_class_variables (self ):
133+ """Test that class variables are properly defined."""
134+ print (f"\n { '=' * 60 } " )
135+ print ("TEST: test_t1ddka_prediction_class_variables()" )
136+ print (f"{ '=' * 60 } " )
137+
138+ # Test T1DM codes
139+ self .assertEqual (T1DDKAPredictionMIMIC4 .T1DM_ICD10_PREFIX , "E10" )
140+ self .assertIn ("25001" , T1DDKAPredictionMIMIC4 .T1DM_ICD9_CODES )
141+ print (f"✓ T1DM ICD-10 prefix: { T1DDKAPredictionMIMIC4 .T1DM_ICD10_PREFIX } " )
142+ print (f"✓ T1DM ICD-9 codes: { len (T1DDKAPredictionMIMIC4 .T1DM_ICD9_CODES )} codes" )
143+
144+ # Test lab categories
145+ self .assertEqual (len (T1DDKAPredictionMIMIC4 .LAB_CATEGORY_ORDER ), 10 )
146+ expected_categories = ["Sodium" , "Potassium" , "Chloride" , "Bicarbonate" , "Glucose" , "Calcium" , "Magnesium" , "Anion Gap" , "Osmolality" , "Phosphate" ]
147+ self .assertEqual (T1DDKAPredictionMIMIC4 .LAB_CATEGORY_ORDER , expected_categories )
148+ print (f"✓ Lab categories: { T1DDKAPredictionMIMIC4 .LAB_CATEGORY_ORDER } " )
149+ print (f"✓ Total lab item IDs: { len (T1DDKAPredictionMIMIC4 .LABITEMS )} " )
119150
120151 def test_dka_prediction_set_task (self ):
121152 """Test DKAPredictionMIMIC4 task with set_task() method."""
@@ -131,18 +162,15 @@ def test_dka_prediction_set_task(self):
131162 print ("\n Calling dataset.set_task()..." )
132163 sample_dataset = self .dataset .set_task (task )
133164 self .assertIsNotNone (sample_dataset , "set_task should return a dataset" )
134- self .assertTrue (
135- hasattr (sample_dataset , "samples" ), "Sample dataset should have samples"
136- )
137165 print (f"✓ set_task() completed" )
138166
139167 # Check sample count
140- num_samples = len (sample_dataset . samples )
168+ num_samples = len (sample_dataset )
141169 print (f"✓ Generated { num_samples } DKA prediction samples" )
142170
143171 if num_samples > 0 :
144- sample = sample_dataset . samples [0 ]
145- required_keys = ["patient_id" , "record_id" , "diagnoses " , "labs" , "label" ]
172+ sample = sample_dataset [0 ]
173+ required_keys = ["patient_id" , "record_id" , "icd_codes " , "labs" , "label" ]
146174
147175 print (f"\n First sample structure:" )
148176 print (f" Sample keys: { list (sample .keys ())} " )
@@ -151,7 +179,7 @@ def test_dka_prediction_set_task(self):
151179 self .assertIn (key , sample , f"Sample should contain key: { key } " )
152180
153181 # Verify diagnoses format (tuple of times and sequences)
154- diagnoses = sample ["diagnoses " ]
182+ diagnoses = sample ["icd_codes " ]
155183 self .assertIsInstance (diagnoses , tuple , "diagnoses should be a tuple" )
156184 self .assertEqual (len (diagnoses ), 2 , "diagnoses tuple should have 2 elements" )
157185 print (f" - diagnoses: { len (diagnoses [1 ])} admission(s)" )
@@ -168,8 +196,8 @@ def test_dka_prediction_set_task(self):
168196
169197 # Count label distribution
170198 label_counts = {0 : 0 , 1 : 0 }
171- for s in sample_dataset . samples :
172- label_counts [s ["label" ]] += 1
199+ for s in sample_dataset :
200+ label_counts [int ( s ["label" ]. item ()) ] += 1
173201
174202 print (f"\n Label distribution:" )
175203 print (f" - No DKA (0): { label_counts [0 ]} ({ label_counts [0 ]/ num_samples * 100 :.1f} %)" )
@@ -183,6 +211,69 @@ def test_dka_prediction_set_task(self):
183211 traceback .print_exc ()
184212 self .fail (f"Failed to use set_task with DKAPredictionMIMIC4: { e } " )
185213
214+ def test_t1ddka_prediction_set_task (self ):
215+ """Test T1DDKAPredictionMIMIC4 task with set_task() method."""
216+ print (f"\n { '=' * 60 } " )
217+ print ("TEST: test_t1ddka_prediction_set_task()" )
218+ print (f"{ '=' * 60 } " )
219+
220+ print ("Initializing T1DDKAPredictionMIMIC4 task..." )
221+ task = T1DDKAPredictionMIMIC4 ()
222+
223+ # Test using set_task method
224+ try :
225+ print ("\n Calling dataset.set_task()..." )
226+ sample_dataset = self .dataset .set_task (task )
227+ self .assertIsNotNone (sample_dataset , "set_task should return a dataset" )
228+ print (f"✓ set_task() completed" )
229+
230+ # Check sample count
231+ num_samples = len (sample_dataset )
232+ print (f"✓ Generated { num_samples } DKA prediction samples" )
233+
234+ if num_samples > 0 :
235+ sample = sample_dataset [0 ]
236+ required_keys = ["patient_id" , "record_id" , "icd_codes" , "labs" , "label" ]
237+
238+ print (f"\n First sample structure:" )
239+ print (f" Sample keys: { list (sample .keys ())} " )
240+
241+ for key in required_keys :
242+ self .assertIn (key , sample , f"Sample should contain key: { key } " )
243+
244+ # Verify diagnoses format (tuple of times and sequences)
245+ diagnoses = sample ["icd_codes" ]
246+ self .assertIsInstance (diagnoses , tuple , "diagnoses should be a tuple" )
247+ self .assertEqual (len (diagnoses ), 2 , "diagnoses tuple should have 2 elements" )
248+ print (f" - diagnoses: { len (diagnoses [1 ])} admission(s)" )
249+
250+ # Verify labs format (tuple of times and sequences)
251+ labs = sample ["labs" ]
252+ self .assertIsInstance (labs , tuple , "labs should be a tuple" )
253+ self .assertEqual (len (labs ), 2 , "labs tuple should have 2 elements" )
254+ print (f" - labs: { len (labs [1 ])} lab vector(s)" )
255+
256+ # Verify label is binary
257+ self .assertIn (sample ["label" ], [0 , 1 ], "Label should be binary (0 or 1)" )
258+ print (f" - label: { sample ['label' ]} " )
259+
260+ # Count label distribution
261+ label_counts = {0 : 0 , 1 : 0 }
262+ for s in sample_dataset :
263+ label_counts [int (s ["label" ].item ())] += 1
264+
265+ print (f"\n Label distribution:" )
266+ print (f" - No DKA (0): { label_counts [0 ]} ({ label_counts [0 ]/ num_samples * 100 :.1f} %)" )
267+ print (f" - Has DKA (1): { label_counts [1 ]} ({ label_counts [1 ]/ num_samples * 100 :.1f} %)" )
268+
269+ print (f"\n ✓ test_t1ddka_prediction_set_task() passed successfully" )
270+
271+ except Exception as e :
272+ print (f"✗ Failed with error: { e } " )
273+ import traceback
274+ traceback .print_exc ()
275+ self .fail (f"Failed to use set_task with T1DDKAPredictionMIMIC4: { e } " )
276+
186277 def test_dka_prediction_helper_methods (self ):
187278 """Test helper methods of DKAPredictionMIMIC4."""
188279 print (f"\n { '=' * 60 } " )
@@ -191,13 +282,25 @@ def test_dka_prediction_helper_methods(self):
191282
192283 task = DKAPredictionMIMIC4 ()
193284
194- # Test _normalize_icd
195- print ("Testing _normalize_icd()..." )
196- self .assertEqual (task ._normalize_icd ("E10.10" ), "E1010" )
197- self .assertEqual (task ._normalize_icd ("e10.10" ), "E1010" )
198- self .assertEqual (task ._normalize_icd (None ), "" )
199- self .assertEqual (task ._normalize_icd (" 25001 " ), "25001" )
200- print ("✓ _normalize_icd() works correctly" )
285+ # Test _is_dka_code
286+ print ("\n Testing _is_dka_code()..." )
287+ self .assertTrue (task ._is_dka_code ("E10.10" , 10 ))
288+ self .assertTrue (task ._is_dka_code ("E1011" , "10" ))
289+ self .assertTrue (task ._is_dka_code ("25011" , 9 ))
290+ self .assertTrue (task ._is_dka_code ("25013" , "9" ))
291+ self .assertFalse (task ._is_dka_code ("E10.65" , 10 )) # Not DKA
292+ self .assertFalse (task ._is_dka_code (None , 10 ))
293+ print ("✓ _is_dka_code() works correctly" )
294+
295+ print (f"\n ✓ test_dka_prediction_helper_methods() passed successfully" )
296+
297+ def test_t1ddka_prediction_helper_methods (self ):
298+ """Test helper methods of DKAPredictionMIMIC4."""
299+ print (f"\n { '=' * 60 } " )
300+ print ("TEST: test_t1ddka_prediction_helper_methods()" )
301+ print (f"{ '=' * 60 } " )
302+
303+ task = T1DDKAPredictionMIMIC4 ()
201304
202305 # Test _is_t1dm_code
203306 print ("\n Testing _is_t1dm_code()..." )
@@ -220,19 +323,7 @@ def test_dka_prediction_helper_methods(self):
220323 self .assertFalse (task ._is_dka_code (None , 10 ))
221324 print ("✓ _is_dka_code() works correctly" )
222325
223- # Test _deduplicate_preserve_order
224- print ("\n Testing _deduplicate_preserve_order()..." )
225- self .assertEqual (
226- task ._deduplicate_preserve_order (["A" , "B" , "A" , "C" , "B" ]),
227- ["A" , "B" , "C" ]
228- )
229- self .assertEqual (
230- task ._deduplicate_preserve_order ([]),
231- []
232- )
233- print ("✓ _deduplicate_preserve_order() works correctly" )
234-
235- print (f"\n ✓ test_dka_prediction_helper_methods() passed successfully" )
326+ print (f"\n ✓ test_t1ddka_prediction_helper_methods() passed successfully" )
236327
237328
238329if __name__ == "__main__" :
0 commit comments