Spaces:
Sleeping
Sleeping
Update logic/care_gap_engine.py
Browse files- logic/care_gap_engine.py +67 -39
logic/care_gap_engine.py
CHANGED
|
@@ -1,39 +1,67 @@
|
|
| 1 |
-
# File: logic/care_gap_engine.py
|
| 2 |
-
|
| 3 |
-
import pandas as pd
|
| 4 |
-
from datetime import datetime
|
| 5 |
-
|
| 6 |
-
def
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# File: logic/care_gap_engine.py
|
| 2 |
+
|
| 3 |
+
import pandas as pd
|
| 4 |
+
from datetime import datetime
|
| 5 |
+
|
| 6 |
+
def normalize_bool(value):
|
| 7 |
+
if isinstance(value, str):
|
| 8 |
+
value = value.strip().lower()
|
| 9 |
+
if value in ["yes", "true", "1"]:
|
| 10 |
+
return True
|
| 11 |
+
elif value in ["no", "false", "0"]:
|
| 12 |
+
return False
|
| 13 |
+
elif isinstance(value, (int, float)):
|
| 14 |
+
return bool(value)
|
| 15 |
+
return value
|
| 16 |
+
|
| 17 |
+
def normalize_gender(value):
|
| 18 |
+
if isinstance(value, str):
|
| 19 |
+
v = value.strip().lower()
|
| 20 |
+
if v in ["f", "female", "2"]:
|
| 21 |
+
return "F"
|
| 22 |
+
elif v in ["m", "male", "1"]:
|
| 23 |
+
return "M"
|
| 24 |
+
elif isinstance(value, int):
|
| 25 |
+
return "F" if value == 2 else "M"
|
| 26 |
+
return value
|
| 27 |
+
|
| 28 |
+
def evaluate_care_gaps(df: pd.DataFrame, config):
|
| 29 |
+
today = datetime.today()
|
| 30 |
+
rules = config["care_gap_rules"]
|
| 31 |
+
results = []
|
| 32 |
+
|
| 33 |
+
for _, row in df.iterrows():
|
| 34 |
+
gaps = []
|
| 35 |
+
|
| 36 |
+
gender = normalize_gender(row.get('gender'))
|
| 37 |
+
|
| 38 |
+
if gender == 'F' and rules['Breast Cancer Screening']['min_age'] <= row['age'] <= rules['Breast Cancer Screening']['max_age']:
|
| 39 |
+
if not row['last_mammogram'] or (today - pd.to_datetime(row['last_mammogram'], errors='coerce')).days > rules['Breast Cancer Screening']['interval_days']:
|
| 40 |
+
gaps.append("Breast Cancer Screening")
|
| 41 |
+
|
| 42 |
+
if rules['Colorectal Cancer Screening']['min_age'] <= row['age'] <= rules['Colorectal Cancer Screening']['max_age']:
|
| 43 |
+
if not row['last_colonoscopy'] or (today - pd.to_datetime(row['last_colonoscopy'], errors='coerce')).days > rules['Colorectal Cancer Screening']['interval_days']:
|
| 44 |
+
gaps.append("Colorectal Cancer Screening")
|
| 45 |
+
|
| 46 |
+
if row.get('systolic_bp', '') != "" and pd.to_numeric(row['systolic_bp'], errors='coerce') > rules['Blood Pressure Control']['bp_threshold']:
|
| 47 |
+
gaps.append("Blood Pressure Control")
|
| 48 |
+
|
| 49 |
+
if row.get('hba1c_value', '') != "" and pd.to_numeric(row['hba1c_value'], errors='coerce') >= 9:
|
| 50 |
+
gaps.append("Diabetes: Poor HbA1c Control")
|
| 51 |
+
|
| 52 |
+
if not normalize_bool(row.get('FollowUp_Scheduled')) or not normalize_bool(row.get('Primary_Care_Established')):
|
| 53 |
+
gaps.append("Follow-Up Care")
|
| 54 |
+
|
| 55 |
+
previous_readm = row.get('Previous_Readmissions', '')
|
| 56 |
+
if isinstance(previous_readm, str):
|
| 57 |
+
if previous_readm.isdigit() and int(previous_readm) >= 3:
|
| 58 |
+
gaps.append("Readmission Risk")
|
| 59 |
+
elif isinstance(previous_readm, (int, float)) and previous_readm >= 3:
|
| 60 |
+
gaps.append("Readmission Risk")
|
| 61 |
+
|
| 62 |
+
results.append({
|
| 63 |
+
'patient_id': row['patient_id'],
|
| 64 |
+
'care_gaps': gaps
|
| 65 |
+
})
|
| 66 |
+
|
| 67 |
+
return pd.DataFrame(results)
|