diff --git a/formsdb/constants.py b/formsdb/constants.py index 6e80108..c679f2b 100644 --- a/formsdb/constants.py +++ b/formsdb/constants.py @@ -413,6 +413,54 @@ "Sulpride (Dolmatil, Sulpitil, Sulparex)": 5000, } +# Antipsychotic medication (1 mg) equivalent doses to 1 mg Haloperidol using the Leucht table for equivalences +med_idx_drug_equivalent_dose_leucht: Dict[int, float] = { + 238: 0.01089, # Amisulpride (Solian) # 'amisulpride/Solian' + 305: 0.55043, # Aripiprazole (Abilitat, Abilify) # 'aripiprazole/Abilify' + 725: 0.53, # Aripiprazole (Abilitat, Abilify) # 'aripiprazole/Abilify ACUTE INJECTION' + 547: 0.38311, # Aripiprazole (Abilitat, Abilify) # 'aripiprazole LAI/Abilify Maintena' + 723: 0.43923, # Aripiprazole (Abilitat, Abilify) # 'aripiprazole lauroxil LAI/Aristada' + 530: 0.42285, # Asenapine (Saphris) # 'asenapine/Saphris' + 732: 0.67191, # Asenapine (Saphris) # 'asenapine patch/Secuado' + 574: 1.88204, # Brexpiprazole (Rexulti) # 'brexpiprazole/Rexulti' + 721: 0.82962, # Cariprazine (Vraylar) # 'cariprazine/Vraylar' + 256: 0.01073, # Chlorpromazine (Largactil) # 'chlorpromazine/Thorazine' + 257: 0.05, # Chlorpromazine (Largactil) # 'chlorpromazine/Thorazine ACUTE INJECTION' + 69: 0.01043, # Clozapine (Clozaril) # 'clozapine/Clozaril' + 403: 0.83454, # Droperidol (Droleptan) # 'droperidol/Inapsine' + 727: 3.2, # Droperidol (Droleptan) # 'droperidol/Inapsine ACUTE INJECTION' + 220: 1, # Fluphenazine HCL (Anatensol) # 'fluphenazine/Prolixin/Permitil' + 222: 4.63634, # Fluphenazine HCL (Anatensol) # 'fluphenazine LAI/Prolixin Decanoate' + 122: 1, # Haloperidol (Haldol) # 'haloperidol/Haldol' + 123: 1, # Haloperidol (Haldol) # 'haloperidol/Haldol ACUTE INJECTION' + 124: 1.54545, # Haloperidol (Haldol) # 'haloperidol LAI/Haldol Decanoate' + 532: 0.31446, # Iloperidone (Fanapt) # 'iloperidone/Fanapt' + 728: 0.18238, # Lumateperone (Caplyta) # 'lumateperone/Caplyta' + 540: 0.04305, # Lurasidone (Latuda) # 'lurasidone/Latuda' + 201: 0.41727, # Olanzapine (Zyprexa) # 'olanzapine/Zyprexa/Symbyax/Lybalvi ' + 726: 0.5, # Olanzapine (Zyprexa) # 'olanzapine/Zyprexa ACUTE INJECTION' + 720: 0.31972, # Olanzapine (Zyprexa) # 'olanzapine LAI/Relprevv' + 531: 0.47416, # Paliperidone (Invega) # 'paliperidone/Invega' + 546: 0.65954, # Paliperidone (Invega) # 'paliperidone palmitate LAI/Invega Sustenna' + 722: 0.56532, # Paliperidone (Invega) # 'paliperidone palmitate LAI/Invega Trinza' + 408: 1.04318, # Pimozide (Orap) # 'pimozide/Orap' + 270: 0.28005, # Perphenazine (Trilafon) # 'perphenazine/Trilafon' + 271: 0.5, # Perphenazine (Trilafon) # 'perphenazine/Trilafon ACUTE INJECTION' + 235: 0.01313, # Quetiapine Fumarate (Seroquel) # 'quetiapine/Seroquel' + 300: 1.01118, # Risperidone (Risperdal) # 'risperidone/Risperdal' + 425: 2.42396, # Risperidone (Risperdal) # 'risperidone LAI/Risperdal Consta' + 452: 1.987, # Risperidone (Risperdal) # 'risperidone SC LAI/Perseris' + 184: 0.27957, # Thiothixene (Navane) # 'thiothixene/Navane' + 158: 0.01669, # Thioridazine (Melleril, Aldazine) # 'thioridazine/Mellaril' + 244: 0.41727, # Trifluoperazine (Stelazine) # 'trifluoperazine/Stelazine' + 245: 1, # Trifluoperazine (Stelazine) # 'trifluoperazine/Stelazine ACUTE INJECTION' + 304: 0.03396, # Ziprasidone (Geodon) # 'ziprasidone/Geodon' + 724: 0.25, # Ziprasidone (Geodon) # 'ziprasidone/Geodon ACUTE INJECTION' + 538: 0.03396, # Ziprasidone (Geodon) # 'ziprasidone/Geodon or placebo (Blinded)' + 75: 0.09597, # Prochlorperazine (Compazine) # 'prochlorperazine/Compazine' + 76: 0.23, # Prochlorperazine (Compazine) # 'prochlorperazine/Compazine ACUTE INJECTION' + 242: 0.02667, # Promazine (Sparine) # 'promazine/Sparine' +} antidepressant_fluoxetine_40mg_drug_equivalent_dose: Dict[str, float] = { "fluoxetine": 40, "agomelatine": 53.2, diff --git a/formsdb/runners/compute/compute_medication_effects.py b/formsdb/runners/compute/compute_medication_effects.py index eb04b4b..c14f1b0 100644 --- a/formsdb/runners/compute/compute_medication_effects.py +++ b/formsdb/runners/compute/compute_medication_effects.py @@ -243,7 +243,7 @@ def get_medication_duaraion_i( duration = len(dates) if duration == 0: - return pd.NA, pd.NA, pd.NA # type: ignore[return] + return pd.NA, pd.NA, pd.NA, pd.NA # type: ignore[return] avg_dosage = sum(total_dosage_by_date.values()) / duration complied_avg_dosage = sum(complied_total_dosage_by_date.values()) / duration @@ -545,7 +545,7 @@ def get_subject_medication_effect_info( # logger.warning(f"Processing {modality} - {timepoint} for {subject_id} on {subject_date_dt}") currently_taking, potential_currently_taking, taken_before = ( get_medication_status( - medication_df=subject_medication_data, target_date=subject_date_dt + medication_df=subject_medication_data, target_date=subject_date_dt # type: ignore ) ) @@ -567,12 +567,12 @@ def get_subject_medication_effect_info( ever_used = med_idx in taken_before result = get_medication_duaraion_i( - medication_df=subject_medication_data, + medication_df=subject_medication_data, # type: ignore target_medication_idx=med_idx, target_date=subject_date_dt, ) is_ongoing = is_medication_ongoing( - medication_df=subject_medication_data, + medication_df=subject_medication_data, # type: ignore target_medication_idx=med_idx, target_date=subject_date_dt, ) @@ -581,7 +581,7 @@ def get_subject_medication_effect_info( days_since_last_taken = 0 else: last_taken_date = date_last_taken( - medication_df=subject_medication_data, + medication_df=subject_medication_data, # type: ignore target_medication_idx=med_idx, target_date=subject_date_dt, ) @@ -608,6 +608,8 @@ def get_subject_medication_effect_info( if pd.isna(dosage_prescribed) or pd.isna(duration_prescribed): ap_equivalent_drug_dose_prescribed = pd.NA ap_equivalent_drug_dose_estimated_taken = pd.NA + ap_equivalent_drug_dose_prescribed_leucht = pd.NA + ap_equivalent_drug_dose_estimated_taken_leucht = pd.NA bd_equivalent_drug_dose_prescribed = pd.NA bd_equivalent_drug_dose_estimated_taken = pd.NA else: @@ -617,6 +619,11 @@ def get_subject_medication_effect_info( int(med_idx), None ) ) + ap_standard_equivalent_drug_dose_leucht = ( + constants.med_idx_drug_equivalent_dose_leucht.get( + int(med_idx), None + ) + ) if ap_standard_equivalent_drug_dose is not None: prescribed_eq_dosage_for_day = dosage_prescribed * ( 50 / ap_standard_equivalent_drug_dose @@ -643,9 +650,36 @@ def get_subject_medication_effect_info( # ) ap_equivalent_drug_dose_prescribed = pd.NA ap_equivalent_drug_dose_estimated_taken = pd.NA + if ap_standard_equivalent_drug_dose_leucht is not None: + prescribed_eq_dosage_for_day_leucht = ( + dosage_prescribed * ap_standard_equivalent_drug_dose_leucht + ) + ap_equivalent_drug_dose_prescribed_leucht = ( + prescribed_eq_dosage_for_day_leucht * duration_prescribed + ) + + if complied_dosage is not None: + complied_equivalent_drug_dose_for_day_leucht = ( + complied_dosage * ap_standard_equivalent_drug_dose_leucht + ) + else: + complied_equivalent_drug_dose_for_day_leucht = pd.NA + ap_equivalent_drug_dose_estimated_taken_leucht = ( + complied_equivalent_drug_dose_for_day_leucht + * duration_prescribed + ) + else: + # logger.warning( + # f"Missing AP Standard Equivalent Drug Dose for " + # f"{med_idx}" + # ) + ap_equivalent_drug_dose_prescribed_leucht = pd.NA + ap_equivalent_drug_dose_estimated_taken_leucht = pd.NA else: ap_equivalent_drug_dose_prescribed = pd.NA ap_equivalent_drug_dose_estimated_taken = pd.NA + ap_equivalent_drug_dose_prescribed_leucht = pd.NA + ap_equivalent_drug_dose_estimated_taken_leucht = pd.NA if med_class == "BENZODIAZEPINE": bd_med_name: str = med_info[int(med_idx)]["med_name"] @@ -718,6 +752,8 @@ def get_subject_medication_effect_info( if ever_used_inconclusive: ap_equivalent_drug_dose_prescribed = pd.NA ap_equivalent_drug_dose_estimated_taken = pd.NA + ap_equivalent_drug_dose_prescribed_leucht = pd.NA + ap_equivalent_drug_dose_estimated_taken_leucht = pd.NA bd_equivalent_drug_dose_prescribed = pd.NA bd_equivalent_drug_dose_estimated_taken = pd.NA @@ -744,6 +780,8 @@ def get_subject_medication_effect_info( "days_since_last_taken": days_since_last_taken, "ap_equivalent_drug_dose_prescribed": ap_equivalent_drug_dose_prescribed, "ap_equivalent_drug_dose_estimated_taken": ap_equivalent_drug_dose_estimated_taken, + "ap_equivalent_drug_dose_prescribed_leucht": ap_equivalent_drug_dose_prescribed_leucht, + "ap_equivalent_drug_dose_estimated_taken_leucht": ap_equivalent_drug_dose_estimated_taken_leucht, "bd_equivalent_drug_dose_prescribed": bd_equivalent_drug_dose_prescribed, "bd_equivalent_drug_dose_estimated_taken": bd_equivalent_drug_dose_estimated_taken, "med_use": med_use, @@ -798,7 +836,7 @@ def compile_medication_effects( # f"Randomly selected {len(subjects)} subjects for processing (out of {len(all_subjects)} total subjects)." # ) - num_processes = multiprocessing.cpu_count() // 2 + num_processes = multiprocessing.cpu_count() logger.info(f"Using {num_processes} processes for parallel computation.") params = [(config_file, subject_id) for subject_id in subjects] @@ -815,6 +853,8 @@ def compile_medication_effects( "days_from_consent", "ap_equivalent_drug_dose_prescribed", "ap_equivalent_drug_dose_estimated_taken", + "ap_equivalent_drug_dose_prescribed_leucht", + "ap_equivalent_drug_dose_estimated_taken_leucht", "bd_equivalent_drug_dose_prescribed", "bd_equivalent_drug_dose_estimated_taken", "duration_prescribed_days", diff --git a/formsdb/runners/compute/compute_medication_effects_by_class.py b/formsdb/runners/compute/compute_medication_effects_by_class.py index d23843d..ffb3a17 100644 --- a/formsdb/runners/compute/compute_medication_effects_by_class.py +++ b/formsdb/runners/compute/compute_medication_effects_by_class.py @@ -179,9 +179,17 @@ def sum_or_none(series: pd.Series) -> Optional[Union[int, float]]: ap_equivalent_drug_dose_estimated_taken = sum_or_none( med_class_df["ap_equivalent_drug_dose_estimated_taken"] ) + ap_equivalent_drug_dose_prescribed_leucht = sum_or_none( + med_class_df["ap_equivalent_drug_dose_prescribed_leucht"] + ) + ap_equivalent_drug_dose_estimated_taken_leucht = sum_or_none( + med_class_df["ap_equivalent_drug_dose_estimated_taken_leucht"] + ) else: ap_equivalent_drug_dose_prescribed = None ap_equivalent_drug_dose_estimated_taken = None + ap_equivalent_drug_dose_prescribed_leucht = None + ap_equivalent_drug_dose_estimated_taken_leucht = None if med_class == "BENZODIAZEPINE": bd_equivalent_drug_dose_prescribed = sum_or_none( @@ -221,6 +229,8 @@ def sum_or_none(series: pd.Series) -> Optional[Union[int, float]]: "ever_used": ever_used, "ap_equivalent_drug_dose_prescribed": ap_equivalent_drug_dose_prescribed, "ap_equivalent_drug_dose_estimated_taken": ap_equivalent_drug_dose_estimated_taken, + "ap_equivalent_drug_dose_prescribed_leucht": ap_equivalent_drug_dose_prescribed_leucht, + "ap_equivalent_drug_dose_estimated_taken_leucht": ap_equivalent_drug_dose_estimated_taken_leucht, "bd_equivalent_drug_dose_prescribed": bd_equivalent_drug_dose_prescribed, "bd_equivalent_drug_dose_estimated_taken": bd_equivalent_drug_dose_estimated_taken, "prescribed_equivalent_drug_dose_for_day": @@ -281,6 +291,8 @@ def compile_medication_effects( "days_from_consent", "ap_equivalent_drug_dose_prescribed", "ap_equivalent_drug_dose_estimated_taken", + "ap_equivalent_drug_dose_prescribed_leucht", + "ap_equivalent_drug_dose_estimated_taken_leucht", "bd_equivalent_drug_dose_prescribed", "bd_equivalent_drug_dose_estimated_taken", "current_use",