From d960d43da44b9af40527bce5a36ce07f4b9fcd62 Mon Sep 17 00:00:00 2001 From: Matthew Reyna Date: Thu, 19 Mar 2026 11:13:00 -0400 Subject: [PATCH] Update PSG montages --- channel_table.csv | 40 ++++++++++++++++++++-------------------- team_code.py | 14 +++++++++----- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/channel_table.csv b/channel_table.csv index cba7fd7..8de22ba 100644 --- a/channel_table.csv +++ b/channel_table.csv @@ -1,10 +1,10 @@ Channel_Names,Category,Description -f3-m2;f3m2;f3-m2+m1;eeg f3-a2;f3-a2;f3:m2;m2:f3;f3:a2;a2:f3;f3-avg,eeg, -f4-m1;f4m1;f4-m1+m2;eeg f4-a1;f4-a1;f4:m1;m1:f4;f4:a1;a1:f4;f4-avg,eeg, -c3-m2;c3m2;c3-m2+m1;eeg c3-a2;c3-a2;c3:m2;m2:c3;c3:a2;a2:c3;c3-avg,eeg, -c4-m1;c4m1;c4-m1+m2;eeg c4-a1;c4-a1;c4:m1;m1:c4;c4:a1;a1:c4;c4-avg,eeg, -o1-m2;o1m2;o1-m2+m1;eeg o1-a2;o1-a2;o1:m2;m2:o1;o1:a2;a2:o1;o1-avg,eeg, -o2-m1;o2m1;o2-m1+m2;eeg o2-a1;o2-a1;o2:m1;m1:o2;o2:a1;a1:o2;o2-avg,eeg, +f3-m2;f3m2;f3-m2+m1;eeg f3-a2;f3-a2;f3:m2;m2:f3;f3:a2;f3/m2;f3/a2;a2:f3;f3-avg,eeg, +f4-m1;f4m1;f4-m1+m2;eeg f4-a1;f4-a1;f4:m1;m1:f4;f4:a1;f4/m1;f4/a1;a1:f4;f4-avg,eeg, +c3-m2;c3m2;c3-m2+m1;eeg c3-a2;c3-a2;c3:m2;m2:c3;c3:a2;c3/m2;c3/a2;a2:c3;c3-avg,eeg, +c4-m1;c4m1;c4-m1+m2;eeg c4-a1;c4-a1;c4:m1;m1:c4;c4:a1;c4/m1;c4/a1;a1:c4;c4-avg,eeg, +o1-m2;o1m2;o1-m2+m1;eeg o1-a2;o1-a2;o1:m2;m2:o1;o1:a2;o1/m2;o1/a2;a2:o1;o1-avg,eeg, +o2-m1;o2m1;o2-m1+m2;eeg o2-a1;o2-a1;o2:m1;m1:o2;o2:a1;o2/m1;o2/a1;a1:o2;o2-avg,eeg, m1;a1,eeg, m2;a2,eeg, f3,eeg, @@ -17,20 +17,20 @@ e1,eog, e2,eog, e2-m1;roc;eog(r);eog-r;eog r;eog2;rt eye (e2);rt. Eye (e2);eog roc-a1;eog roc-a2;roc-a1;eog roc-m1;roc-m1;r-eog;e2-m2;e2:m1;m1:e2;e2:a1;a1:e2;e1-avg,eog, e1-m2;loc;eog(l);eog-l;eog l;eog1;lt eye (e1);lt. eye (e1);eog loc-a1;eog loc-a2;loc-a2;eog loc-m2;loc-m2;l-eog;e1-m1;e1:m2;m2:e1;e1:a2;a2:e1;e2-avg,eog, -chin1-chin2;chin1chin2;chin;china;chin_emg;emg.subm;emg;chin emg;emg chin;emg-chin;chin1-chin3,chin emg, -chin 1;l chin;chin l;chinl;chin1;emg1;chin_emg1;chin emg 1;chin emg 1,chin emg, -chin 2;r chin;chin r;chinr;chin2;emg2;chin_emg2;chin emg 2;chin emg 2,chin emg, -lat;l leg;lleg;left leg;left_leg;l emg;lemg;leg 1;leg1;leg-l;plml,leg emg, -rat;r leg;rleg;right leg;right_leg;r emg;remg;l/rat;emg-leg;leg;legs;leg 2;leg2;leg-r;plmr,leg emg, -rleg+;rat1;rat 1;rat-u,leg emg, -rleg-;rat2;rat 2;rat-l,leg emg, -lleg+;lat1;lat 1;lat-u,leg emg, -lleg-;lat2;lat 2;lat-l,leg emg, -ecg;ekg;ecg-la;ecg-v1;ecg-v2;ecg-ll;ecg-ra;ecg l;ecgl;ecg i;ecg ii,ecg, -abd;abdomen;abdominal;abd res;abdo res;abdo;effort abd;abdominal effort;abdom,resp, -chest;thorax;thoracic;thor res;thoracic res;chest res;thor;effort tho;thoracic effort,resp, +chin1-chin2;chin1chin2;chin;china;chin_emg;emg.subm;emg;chin emg;emg chin;emg-chin;chin1-chin3;chin-a;emg1-emg2,chin emg, +chin 1;l chin;chin l;chinl;chin1;emg1;chin_emg1;chin emg 1;chin emg 1;chin-l;emg1,chin emg, +chin 2;r chin;chin r;chinr;chin2;emg2;chin_emg2;chin emg 2;chin emg 2;chin-r;emg2,chin emg, +lat;l leg;lleg;left leg;left_leg;l emg;lemg;leg 1;leg1;leg-l;plml;l-leg;gnd-leg l,leg emg, +rat;r leg;rleg;right leg;right_leg;r emg;remg;l/rat;emg-leg;leg;legs;leg 2;leg2;leg-r;plmr;r-leg;gnd-leg r,leg emg, +rleg+;rat1;rat 1;rat-u;r-leg1,leg emg, +rleg-;rat2;rat 2;rat-l;r-leg2,leg emg, +lleg+;lat1;lat 1;lat-u;l-leg1,leg emg, +lleg-;lat2;lat 2;lat-l;l-leg2,leg emg, +ecg;ekg;ecg-la;ecg-v1;ecg-v2;ecg-ll;ecg-ra;ecg l;ecgl;ecg i;ecg ii;ekg-r;ekg-l;ecg1;ecg2;ecg ref-ecg1;ecg ref-ecg2;ecg ref-ecg3,ecg, +abd;abdomen;abdominal;abd res;abdo res;abdo;effort abd;abdominal effort;abdom;respitrace abdom,resp, +chest;thorax;thoracic;thor res;thoracic res;chest res;thor;effort tho;thoracic effort;respitrace chest,resp, ptaf;pressure;npt;nptaf;nasal_pressure;nasal pressure;nasal;nasaloral;nasal oral;cannula;cannula_flow;cannula flow;nasal cannula;nasal canula;nasal flow;nasalflow,resp, -airflow;flow_dr;flow;air flow;thermal airflow;airflow thermal;airflow2;flow ii;thermal;therm;thermal flow;thermistor;thermistor 2;thermister,resp, +airflow;flow_dr;flow;air flow;thermal airflow;airflow thermal;airflow2;flow ii;thermal;therm;thermal flow;thermistor;thermistor 2;thermister;gnd-flow,resp, cflow;c-flow;c flow;cpap flow;cflowext;cflowresmed,resp, cpres;cpress;c press;c_press;cpap pressure;cpap_press;c-pres;c-press;cpap-pressure;cpap pres;cpap press;cpap pressure 1;cpressure,resp, -spo2;sao2;osat;o2sat;o2 sat;o2-sat;o2-saturation,resp, +spo2;sao2;osat;o2sat;o2 sat;o2-sat;o2-saturation;gnd-spo2,resp, diff --git a/team_code.py b/team_code.py index a055222..910c4ed 100644 --- a/team_code.py +++ b/team_code.py @@ -269,8 +269,12 @@ def extract_physiological_features(physiological_data, physiological_fs, csv_pat new_label = rename_map.get(old_label, old_label.lower()) processed_channels[new_label] = data # Mapping the sampling rate to the new label - processed_fs[new_label] = physiological_fs.get(old_label, 200.0) # Default to 200 if missing - + if old_label in physiological_fs: + processed_fs[new_label] = physiological_fs[old_label] + else: + # Report error and stop if no FS is found for a kept channel + raise KeyError(f"Sampling frequency (fs) not found for channel '{old_label}' ") + if 'physiological_data' in locals(): del physiological_data # Step 3: Construct Bipolar Derivations @@ -279,7 +283,7 @@ def extract_physiological_features(physiological_data, physiological_fs, csv_pat ('c3-m2', 'c3', ['m2']), ('c4-m1', 'c4', ['m1']), ('o1-m2', 'o1', ['m2']), ('o2-m1', 'o2', ['m1']), ('e1-m2', 'e1', ['m2']), ('e2-m1', 'e2', ['m1']), - ('chin1-chin2', 'chin1', ['chin2']), + ('chin1-chin2', 'chin 1', ['chin 2']), ('lat', 'lleg+', ['lleg-']), ('rat', 'rleg+', ['rleg-']) ] @@ -433,7 +437,7 @@ def count_discrete_events(key): features.extend([ahi_auto, arousal_auto, limb_auto]) # --- 2. Sleep Architecture (from stage_caisr) --- - # Standard labels: 0=W, 1=N1, 2=N2, 3=N3, 4=R (or similar mapping) + # Standard labels: 5=W, 4=R, 3=N1, 2=N2, 1=N3 (or similar mapping) stages = algo_data.get('stage_caisr', np.array([])) # Filter out invalid/background values (like the 9.0 in your sample) valid_stages = stages[stages < 9.0] @@ -448,7 +452,7 @@ def count_discrete_events(key): n3_pct = np.mean(valid_stages == 1) # Sleep Efficiency: (N1+N2+N3+R) / Total - efficiency = np.mean(valid_stages > 0) + efficiency = np.mean((valid_stages >= 1) & (valid_stages <= 4)) else: w_pct = n1_pct = n2_pct = n3_pct = r_pct = efficiency = 0.0