diff --git a/resources/costing/ResourceFile_Costing.xlsx b/resources/costing/ResourceFile_Costing.xlsx new file mode 100644 index 0000000000..9f06132aaa --- /dev/null +++ b/resources/costing/ResourceFile_Costing.xlsx @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2afa3649672e10c9741b26dc70fa0f4496af4fccfafbf8b7b70f3b90b291a4fb +size 1007463 diff --git a/resources/healthsystem/consumables/ResourceFile_Consumables_Items_and_Packages.csv b/resources/healthsystem/consumables/ResourceFile_Consumables_Items_and_Packages.csv index 8af8f070b2..0ee403abb0 100644 --- a/resources/healthsystem/consumables/ResourceFile_Consumables_Items_and_Packages.csv +++ b/resources/healthsystem/consumables/ResourceFile_Consumables_Items_and_Packages.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:85e2c3ba8037e74490751fbb8384709dff1907c785c856f0394f40b4fc024da3 -size 253400 +oid sha256:4106c2e3ae068d40b115857885b673bec3e1114be5183c0a4ae0366560e2a5c9 +size 249391 diff --git a/resources/healthsystem/consumables/ResourceFile_Consumables_availability_small.csv b/resources/healthsystem/consumables/ResourceFile_Consumables_availability_small.csv index 54453cbc2f..25249531b2 100644 --- a/resources/healthsystem/consumables/ResourceFile_Consumables_availability_small.csv +++ b/resources/healthsystem/consumables/ResourceFile_Consumables_availability_small.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69a5143c0b7307c7bb48726aa73d6c2f61de2a69aeb445eec87494cf9d4a1041 -size 6087331 +oid sha256:c358a643e4def0e574b75f89f83d77f9c3366f668422e005150f4d69ebe8d7a7 +size 6169152 diff --git a/resources/healthsystem/consumables/ResourceFile_consumables_matched.csv b/resources/healthsystem/consumables/ResourceFile_consumables_matched.csv index 7754d65118..7ab675ecba 100644 --- a/resources/healthsystem/consumables/ResourceFile_consumables_matched.csv +++ b/resources/healthsystem/consumables/ResourceFile_consumables_matched.csv @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fbfe91222d3a2a32ed44a4be711b30c5323276a71df802f6c9249eb4c21f8d43 -size 90158 +oid sha256:b5b0f417681cbdd2489e2f9c6634b2825c32beb9637dc045b56e308c910a102c +size 90569 diff --git a/src/scripts/data_file_processing/healthsystem/consumables/consumable_resource_analyses_with_lmis/consumables_availability_estimation.py b/src/scripts/data_file_processing/healthsystem/consumables/consumable_resource_analyses_with_lmis/consumables_availability_estimation.py index 2495ea6d66..3615afd400 100644 --- a/src/scripts/data_file_processing/healthsystem/consumables/consumable_resource_analyses_with_lmis/consumables_availability_estimation.py +++ b/src/scripts/data_file_processing/healthsystem/consumables/consumable_resource_analyses_with_lmis/consumables_availability_estimation.py @@ -277,14 +277,10 @@ def custom_agg(x): return _collapsed_df # Hold out the dataframe with no naming inconsistencies -list_of_items_with_inconsistent_names_zipped = list( - zip(inconsistent_item_names_mapping.keys(), inconsistent_item_names_mapping.values())) -list_of_items_with_inconsistent_names = [ - item for sublist in list_of_items_with_inconsistent_names_zipped for item in sublist] -df_with_consistent_item_names = lmis_df_wide_flat[~lmis_df_wide_flat[('item',)].isin( - list_of_items_with_inconsistent_names)] -df_without_consistent_item_names = lmis_df_wide_flat[lmis_df_wide_flat[('item',)].isin( - list_of_items_with_inconsistent_names)] +list_of_items_with_inconsistent_names_zipped = set(zip(inconsistent_item_names_mapping.keys(), inconsistent_item_names_mapping.values())) +list_of_items_with_inconsistent_names = [item for sublist in list_of_items_with_inconsistent_names_zipped for item in sublist] +df_with_consistent_item_names = lmis_df_wide_flat[~lmis_df_wide_flat[('item',)].isin(list_of_items_with_inconsistent_names)] +df_without_consistent_item_names = lmis_df_wide_flat[lmis_df_wide_flat[('item',)].isin(list_of_items_with_inconsistent_names)] # Make inconsistently named drugs uniform across the dataframe df_without_consistent_item_names_corrected = rename_items_to_address_inconsistentencies( df_without_consistent_item_names, inconsistent_item_names_mapping) diff --git a/src/scripts/data_file_processing/healthsystem/consumables/processing_data_from_one_health/generate_consumables_item_codes_and_packages.py b/src/scripts/data_file_processing/healthsystem/consumables/processing_data_from_one_health/generate_consumables_item_codes_and_packages.py index 3fcbccf9e2..7ca04f763f 100644 --- a/src/scripts/data_file_processing/healthsystem/consumables/processing_data_from_one_health/generate_consumables_item_codes_and_packages.py +++ b/src/scripts/data_file_processing/healthsystem/consumables/processing_data_from_one_health/generate_consumables_item_codes_and_packages.py @@ -21,7 +21,8 @@ # Set local Dropbox source path_to_dropbox = Path( # <-- point to the TLO dropbox locally - '/Users/tbh03/Dropbox (SPH Imperial College)/Thanzi la Onse Theme 1 SHARE') + # '/Users/tbh03/Dropbox (SPH Imperial College)/Thanzi la Onse Theme 1 SHARE' + '/Users/sm2511/Dropbox/Thanzi La Onse') resourcefilepath = Path("./resources") path_for_new_resourcefiles = resourcefilepath / "healthsystem/consumables" @@ -245,7 +246,7 @@ def add_record(df: pd.DataFrame, record: Dict): """Add a row to the bottom of the dataframe, where the row is specified by a dict keyed by the target columns.""" - assert list(df.columns) == list(record.keys()) + assert set(df.columns) == set(record.keys()) return pd.concat([df, pd.DataFrame.from_records([record])], ignore_index=True) @@ -328,6 +329,54 @@ def add_record(df: pd.DataFrame, record: Dict): }, ) +cons = add_record( + cons, + { + 'Intervention_Cat': "Added by SM (Recommended by TM)", + 'Intervention_Pkg': "Isoniazid preventative therapy for HIV+ no TB", + 'Intervention_Pkg_Code': 82, + 'Items': "Isoniazid/Rifapentine", + 'Item_Code': 2678, + 'Expected_Units_Per_Case': 1.0, + 'Unit_Cost': 1.0 + }, +) + +cons = add_record( + cons, + { + 'Intervention_Cat': "Added by SM (Recommended by EJ)", + 'Intervention_Pkg': "Misc", + 'Intervention_Pkg_Code': -99, + 'Items': "Cystoscope", + 'Item_Code': 285, + 'Expected_Units_Per_Case': 1.0, + 'Unit_Cost': np.nan}, +) + +cons = add_record( + cons,{ + 'Intervention_Cat': "Added by SM (Recommended by EJ)", + 'Intervention_Pkg': "Misc", + 'Intervention_Pkg_Code': -99, + 'Items': "Endoscope", + 'Item_Code': 280, + 'Expected_Units_Per_Case': 1.0, + 'Unit_Cost': np.nan}, +) + +cons = add_record( + cons,{ + 'Intervention_Cat': "Added by SM (Recommended by EJ)", + 'Intervention_Pkg': "Misc", + 'Intervention_Pkg_Code': -99, + 'Items': "Prostate specific antigen test", + 'Item_Code': 281, + 'Expected_Units_Per_Case': 1.0, + 'Unit_Cost': np.nan}, +) + + # -------------- # -------------- # -------------- diff --git a/src/tlo/methods/alri.py b/src/tlo/methods/alri.py index 277726e0ff..61e9ae848b 100644 --- a/src/tlo/methods/alri.py +++ b/src/tlo/methods/alri.py @@ -21,7 +21,6 @@ """ from __future__ import annotations -import types from collections import defaultdict from itertools import chain from pathlib import Path @@ -1014,139 +1013,85 @@ def look_up_consumables(self): get_item_code = self.sim.modules['HealthSystem'].get_item_code_from_item_name - def get_dosage_for_age_in_months(age_in_whole_months: float, doses_by_age_in_months: Dict[int, float]): - """Returns the dose corresponding to age, using the lookup provided in `doses`. The format of `doses` is: - {: }.""" - - for upper_age_bound_in_months, _dose in sorted(doses_by_age_in_months.items()): - if age_in_whole_months < upper_age_bound_in_months: - return _dose - return _dose - - # # # # # # Dosages by age # # # # # # + # # # # # # Dosages by weight # # # # # # + # Assuming average weight of 0-5 is 12kg (abstraction). Doses sourced for WHO Pocket book of hospital care for + # children: Second edition 2014 # Antibiotic therapy ------------------- - # Antibiotics for non-severe pneumonia - oral amoxicillin for 5 days + # Antibiotics for non-severe pneumonia - oral amoxicillin for 5 days (40mg/kg BD - ((12*40)*2)*5 =4800mg) self.consumables_used_in_hsi['Amoxicillin_tablet_or_suspension_5days'] = { - get_item_code(item='Amoxycillin 250mg_1000_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {2: 0, 12: 0.006, 36: 0.012, np.inf: 0.018} - ), - get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {2: 0, 12: 1, 36: 2, np.inf: 3} - ), - } + get_item_code(item='Amoxycillin 250mg_1000_CMST'): 4800, + get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): 192} # 25mg/ml - 4800/25 - # Antibiotics for non-severe pneumonia - oral amoxicillin for 3 days + # Antibiotics for non-severe pneumonia - oral amoxicillin for 3 days (40mg/kg BD - ((12*40)*2)*3 =2880mg) self.consumables_used_in_hsi['Amoxicillin_tablet_or_suspension_3days'] = { - get_item_code(item='Amoxycillin 250mg_1000_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {2: 0, 12: 0.01, 36: 0.02, np.inf: 0.03} - ), - get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {2: 0, 12: 1, 36: 2, np.inf: 3} - ), - } + get_item_code(item='Amoxycillin 250mg_1000_CMST'): 2880, + get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): 115} # 25mg/ml - 2880/25 - # Antibiotics for non-severe pneumonia - oral amoxicillin for 7 days for young infants only + # Antibiotics for non-severe pneumonia - oral amoxicillin for 7 days for young infants only (40mg/kg BD - + # ((12*40)*2)*7 =6720mg) self.consumables_used_in_hsi['Amoxicillin_tablet_or_suspension_7days'] = { - get_item_code(item='Amoxycillin 250mg_1000_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 0.004, 2: 0.006, np.inf: 0.01} - ), - get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 0.4, 2: 0.5, np.inf: 1} - ), - } + get_item_code(item='Amoxycillin 250mg_1000_CMST'): 6720, + get_item_code(item='Amoxycillin 125mg/5ml suspension, PFR_0.025_CMST'): 269} # 25mg/ml - 6720/25 # Antibiotic therapy for severe pneumonia - ampicillin package + # Amp. dose - 50mg/KG QDS 5 days = (50*12)*4)*5 = 12_000mg + # Gent. dose -7.5mg/kg per day 5 days = (7.5*12)*5 = 450mg self.consumables_used_in_hsi['1st_line_IV_antibiotics'] = { - get_item_code(item='Ampicillin injection 500mg, PFR_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 3.73, 2: 5.6, 4: 8, 12: 16, 36: 24, np.inf: 40} - ), - get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 0.7, 2: 1.4, 4: 2.81, 12: 4.69, 36: 7.03, np.inf: 9.37} - ), + get_item_code(item='Ampicillin injection 500mg, PFR_each_CMST'): 24, # 500mg vial -12_000/500 + get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): 6, # 80mg/2ml = 450/8 get_item_code(item='Cannula iv (winged with injection pot) 16_each_CMST'): 1, get_item_code(item='Syringe, Autodisable SoloShot IX '): 1 } # # Antibiotic therapy for severe pneumonia - benzylpenicillin package when ampicillin is not available + # Benpen dose - 50_000IU/KG QDS 5 days = (50_000*12)*4)*5 = 12_000_000IU = 8g (approx) + # Gent. dose -7.5mg/kg per day 5 days = (7.5*12)*5 = 450mg self.consumables_used_in_hsi['Benzylpenicillin_gentamicin_therapy_for_severe_pneumonia'] = { - get_item_code(item='Benzylpenicillin 3g (5MU), PFR_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 2, 2: 5, 4: 8, 12: 15, 36: 24, np.inf: 34} - ), - get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {1: 0.7, 2: 1.4, 4: 2.81, 12: 4.69, 36: 7.03, np.inf: 9.37} - ), + get_item_code(item='Benzylpenicillin 3g (5MU), PFR_each_CMST'): 8, + get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): 6, # 80mg/2ml = 450/8 get_item_code(item='Cannula iv (winged with injection pot) 16_each_CMST'): 1, get_item_code(item='Syringe, Autodisable SoloShot IX '): 1 } # Second line of antibiotics for severe pneumonia, if Staph not suspected + # Ceft. dose = 80mg/kg per day 5 days = (80*12)*5 = 4800mg self.consumables_used_in_hsi['Ceftriaxone_therapy_for_severe_pneumonia'] = { - get_item_code(item='Ceftriaxone 1g, PFR_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {4: 1.5, 12: 3, 36: 5, np.inf: 7} - ), + get_item_code(item='Ceftriaxone 1g, PFR_each_CMST'): 1, # smallest unit is 1g get_item_code(item='Cannula iv (winged with injection pot) 16_each_CMST'): 1, get_item_code(item='Syringe, Autodisable SoloShot IX '): 1 } # Second line of antibiotics for severe pneumonia, if Staph is suspected + # Flucox. dose = 50mg/kg QDS 7 days = ((50*12)*4)*7 = 16_800mg + # Oral flucox dose. = same self.consumables_used_in_hsi['2nd_line_Antibiotic_therapy_for_severe_staph_pneumonia'] = { - get_item_code(item='Flucloxacillin 250mg, vial, PFR_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {2: 21, 4: 22.4, 12: 37.3, 36: 67.2, 60: 93.3, np.inf: 140} - ), - get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {4: 2.81, 12: 4.69, 36: 7.03, 60: 9.37, np.inf: 13.6} - ), + get_item_code(item='Flucloxacillin 250mg, vial, PFR_each_CMST'): 16_800, + get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): 6, # 80mg/2ml = 450/8 get_item_code(item='Cannula iv (winged with injection pot) 16_each_CMST'): 1, get_item_code(item='Syringe, Autodisable SoloShot IX '): 1, - get_item_code(item='Flucloxacillin 250mg_100_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {4: 0.42, 36: 0.84, 60: 1.68, np.inf: 1.68} - ), - } + get_item_code(item='Flucloxacillin 250mg_100_CMST'): 16_800} # First dose of antibiotic before referral ------------------- - + # single dose of 7.5mg gent and 50mg/g amp. given # Referral process in iCCM for severe pneumonia, and at health centres for HIV exposed/infected self.consumables_used_in_hsi['First_dose_oral_amoxicillin_for_referral'] = { - get_item_code(item='Amoxycillin 250mg_1000_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {12: 0.001, 36: 0.002, np.inf: 0.003} - ), + get_item_code(item='Amoxycillin 250mg_1000_CMST'): 250, } # Referral process at health centres for severe cases self.consumables_used_in_hsi['First_dose_IM_antibiotics_for_referral'] = { - get_item_code(item='Ampicillin injection 500mg, PFR_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {4: 0.4, 12: 0.8, 36: 1.4, np.inf: 2} - ), - get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {4: 0.56, 12: 0.94, 36: 1.41, np.inf: 1.87} - ), + get_item_code(item='Ampicillin injection 500mg, PFR_each_CMST'): 2, # 2 x 500mg vial + get_item_code(item='Gentamicin Sulphate 40mg/ml, 2ml_each_CMST'): 2, # assuming single dose at referral get_item_code(item='Cannula iv (winged with injection pot) 16_each_CMST'): 1, get_item_code(item='Syringe, Autodisable SoloShot IX '): 1 } # Oxygen, pulse oximetry and x-ray ------------------- - # Oxygen for hypoxaemia + # Oxygen for hypoxaemia - 5/l per min (Approx) for 3 days ((24*60)*5)*3 self.consumables_used_in_hsi['Oxygen_Therapy'] = { - get_item_code(item='Oxygen, 1000 liters, primarily with oxygen cylinders'): 1, + get_item_code(item='Oxygen, 1000 liters, primarily with oxygen cylinders'): 21_600, } # Pulse oximetry @@ -1162,10 +1107,7 @@ def get_dosage_for_age_in_months(age_in_whole_months: float, doses_by_age_in_mon # Optional consumables ------------------- # Paracetamol self.consumables_used_in_hsi['Paracetamol_tablet'] = { - get_item_code(item='Paracetamol, tablet, 100 mg'): - lambda _age: get_dosage_for_age_in_months(int(_age * 12.0), - {36: 12, np.inf: 18} - ), + get_item_code(item='Paracetamol, tablet, 100 mg'): 240, # 20mg/kg } # Maintenance of fluids via nasograstric tube @@ -1178,11 +1120,6 @@ def get_dosage_for_age_in_months(age_in_whole_months: float, doses_by_age_in_mon get_item_code(item='Salbutamol sulphate 1mg/ml, 5ml_each_CMST'): 2 } - # Bronchodilator - oral - self.consumables_used_in_hsi['Oral_Brochodilator'] = { - get_item_code(item='Salbutamol, syrup, 2 mg/5 ml'): 1, - get_item_code(item='Salbutamol, tablet, 4 mg'): 1 - } def end_episode(self, person_id): """End the episode infection for a person (i.e. reset all properties to show no current infection or @@ -2420,11 +2357,7 @@ def _get_cons(self, _arg: Union[str, Tuple[str]]) -> bool: def _get_cons_group(self, item_group_str: str) -> bool: """True if _all_ of a group of consumables (identified by a string) is available.""" if item_group_str is not None: - return self.get_consumables( - item_codes={ - k: v(self._age_exact_years) if isinstance(v, types.LambdaType) else v - for k, v in self.module.consumables_used_in_hsi[item_group_str].items() - }) + return self.get_consumables(self.module.consumables_used_in_hsi[item_group_str]) else: raise ValueError('String for the group of consumables not provided') diff --git a/src/tlo/methods/cancer_consumables.py b/src/tlo/methods/cancer_consumables.py index 16a6f94f65..2649626b2f 100644 --- a/src/tlo/methods/cancer_consumables.py +++ b/src/tlo/methods/cancer_consumables.py @@ -3,94 +3,89 @@ """ from typing import Dict -from tlo import Module - -def get_consumable_item_codes_cancers(cancer_module: Module) -> Dict[str, int]: +def get_consumable_item_codes_cancers(self) -> Dict[str, int]: """ Returns dict the relevant item_codes for the consumables across the five cancer modules. This is intended to prevent repetition within module code. """ - def get_list_of_items(item_list): - item_lookup_fn = cancer_module.sim.modules['HealthSystem'].get_item_code_from_item_name - return list(map(item_lookup_fn, item_list)) + get_item_code = self.sim.modules['HealthSystem'].get_item_code_from_item_name cons_dict = dict() # Add items that are needed for all cancer modules - # todo: @Eva - add syringes, dressing - cons_dict['screening_biopsy_core'] = get_list_of_items(['Biopsy needle']) + cons_dict['screening_biopsy_core'] = \ + {get_item_code("Biopsy needle"): 1} cons_dict['screening_biopsy_optional'] = \ - get_list_of_items(['Specimen container', - 'Lidocaine, injection, 1 % in 20 ml vial', - 'Gauze, absorbent 90cm x 40m_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + {get_item_code("Specimen container"): 1, + get_item_code("Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 30, + get_item_code("Disposables gloves, powder free, 100 pieces per box"): 1, + get_item_code("Syringe, needle + swab"): 1} cons_dict['treatment_surgery_core'] = \ - get_list_of_items(['Halothane (fluothane)_250ml_CMST', - 'Scalpel blade size 22 (individually wrapped)_100_CMST']) + {get_item_code("Halothane (fluothane)_250ml_CMST"): 100, + get_item_code("Scalpel blade size 22 (individually wrapped)_100_CMST"): 1} cons_dict['treatment_surgery_optional'] = \ - get_list_of_items(['Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Paracetamol, tablet, 500 mg', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Suture pack', - 'Gauze, absorbent 90cm x 40m_each_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST']) + {get_item_code("Sodium chloride, injectable solution, 0,9 %, 500 ml"): 2000, + get_item_code("Paracetamol, tablet, 500 mg"): 8000, + get_item_code("Pethidine, 50 mg/ml, 2 ml ampoule"): 6, + get_item_code("Suture pack"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 30, + get_item_code("Cannula iv (winged with injection pot) 18_each_CMST"): 1} cons_dict['palliation'] = \ - get_list_of_items(['morphine sulphate 10 mg/ml, 1 ml, injection (nt)_10_IDA', - 'Diazepam, injection, 5 mg/ml, in 2 ml ampoule', - # N.B. This is not an exhaustive list of drugs required for palliation - ]) - - cons_dict['iv_drug_cons'] = \ - get_list_of_items(['Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box' - ]) + {get_item_code("morphine sulphate 10 mg/ml, 1 ml, injection (nt)_10_IDA"): 1, + get_item_code("Diazepam, injection, 5 mg/ml, in 2 ml ampoule"): 3, + get_item_code("Syringe, needle + swab"): 4} + # N.B. This is not an exhaustive list of drugs required for palliation - # Add items that are specific to each cancer module - if 'BreastCancer' == cancer_module.name: + cons_dict['treatment_chemotherapy'] = \ + {get_item_code("Cyclophosphamide, 1 g"): 16800} - # TODO: chemotharpy protocols??: TAC(Taxotere, Adriamycin, and Cyclophosphamide), AC (anthracycline and - # cyclophosphamide) +/-Taxane, TC (Taxotere and cyclophosphamide), CMF (cyclophosphamide, methotrexate, - # and fluorouracil), FEC-75 (5-Fluorouracil, Epirubicin, Cyclophosphamide). HER 2 +: Add Trastuzumab - - # only chemotherapy i consumable list which is also in suggested protocol is cyclo - cons_dict['treatment_chemotherapy'] = get_list_of_items(['Cyclophosphamide, 1 g']) + cons_dict['iv_drug_cons'] = \ + {get_item_code("Cannula iv (winged with injection pot) 18_each_CMST"): 1, + get_item_code("Giving set iv administration + needle 15 drops/ml_each_CMST"): 1, + get_item_code("Disposables gloves, powder free, 100 pieces per box"): 1, + get_item_code("Gauze, swabs 8-ply 10cm x 10cm_100_CMST"): 84} - elif 'ProstateCancer' == cancer_module.name: + # Add items that are specific to a particular cancer module + if 'ProstateCancer' == self.name: - # TODO: Prostate specific antigen test is listed in ResourceFile_Consumables_availability_and_usage but not - # ResourceFile_Consumables_Items_and_Package - # cons_dict['screening_psa_test_core'] = get_list_of_items(['Prostate specific antigen test']) + cons_dict['screening_psa_test_core'] = \ + {get_item_code("Prostate specific antigen test"): 1} cons_dict['screening_psa_test_optional'] = \ - get_list_of_items(['Blood collecting tube, 5 ml', - 'Disposables gloves, powder free, 100 pieces per box']) + {get_item_code("Blood collecting tube, 5 ml"): 1, + get_item_code("Disposables gloves, powder free, 100 pieces per box"): 1, + get_item_code("Gauze, swabs 8-ply 10cm x 10cm_100_CMST"): 1} - elif 'BladderCancer' == cancer_module.name: + elif 'BladderCancer' == self.name: # Note: bladder cancer is not in the malawi STG 2023 therefore no details on chemotherapy - # TODO: cytoscope is listed in ResourceFile_Consumables_availability_and_usage but not - # ResourceFile_Consumables_Items_and_Packages - # cons_dict['screening_cystoscopy_core'] = get_list_of_items(['Cytoscope']) - - cons_dict['screening_cystoscope_optional'] = get_list_of_items(['Specimen container']) + cons_dict['screening_cystoscopy_core'] = \ + {get_item_code("Cystoscope"): 1} - elif 'OesophagealCancer' == cancer_module.name: + cons_dict['screening_cystoscope_optional'] = \ + {get_item_code("Specimen container"): 1, + get_item_code("Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 30, + get_item_code("Disposables gloves, powder free, 100 pieces per box"): 1, + get_item_code("Syringe, needle + swab"): 1} - # TODO: endoscope is listed in ResourceFile_Consumables_availability_and_usage but not - # ResourceFile_Consumables_Items_and_Packages - # cons_dict['screening_endoscope_core'] = get_list_of_items(['Endoscope']) + elif 'OesophagealCancer' == self.name: - cons_dict['screening_endoscope_optional'] =\ - get_list_of_items(['Specimen container', - 'Gauze, absorbent 90cm x 40m_each_CMST']) + cons_dict['screening_endoscope_core'] = \ + {get_item_code("Endoscope"): 1} - cons_dict['treatment_chemotherapy'] = get_list_of_items(['Cisplatin 50mg Injection']) + cons_dict['screening_endoscope_optional'] = \ + {get_item_code("Specimen container"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 30, + get_item_code("Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml"): 1, + get_item_code("Disposables gloves, powder free, 100 pieces per box"): 1, + get_item_code("Syringe, needle + swab"): 1} return cons_dict diff --git a/src/tlo/methods/cardio_metabolic_disorders.py b/src/tlo/methods/cardio_metabolic_disorders.py index 921b2e0f71..1d5f47ecb9 100644 --- a/src/tlo/methods/cardio_metabolic_disorders.py +++ b/src/tlo/methods/cardio_metabolic_disorders.py @@ -1600,10 +1600,23 @@ def apply(self, person_id, squeeze_factor): return self.sim.modules['HealthSystem'].get_blank_appt_footprint() assert person[f'nc_{self.condition}_ever_diagnosed'], "The person is not diagnosed and so should not be " \ "receiving an HSI." + + # Monthly doses of medications as follows. Diabetes - 1000mg metformin daily (1000*30.5), + # hypertension - 25mg hydrochlorothiazide daily (25*30.5), CKD 1 dialysis bag (estimate), + # lower back pain - 2400mg aspirin daily (2400*30.5), CIHD - 75mg aspirin daily (75*30.5) + dose = {'diabetes': 30_500, + 'hypertension': 610, + 'chronic_kidney_disease': 1, + 'chronic_lower_back_pain': 73_200, + 'chronic_ischemic_hd': 2288, + 'ever_stroke': 2288, + 'ever_heart_attack': 2288} + # Check availability of medication for condition - if self.get_consumables( - item_codes=self.module.parameters[f'{self.condition}_hsi'].get('medication_item_code').astype(int) - ): + if self.get_consumables(item_codes= + {self.module.parameters[f'{self.condition}_hsi'].get( + 'medication_item_code').astype(int): dose[self.condition]}): + # If medication is available, flag as being on medication df.at[person_id, f'nc_{self.condition}_on_medication'] = True # Determine if the medication will work to prevent death @@ -1669,10 +1682,21 @@ def apply(self, person_id, squeeze_factor): # Return the blank_appt_footprint() so that this HSI does not occupy any time resources return self.sim.modules['HealthSystem'].get_blank_appt_footprint() + # Monthly doses of medications as follows. Diabetes - 1000mg metformin daily (1000*30.5), + # hypertension - 25mg hydrochlorothiazide daily (25*30.5), CKD 1 dialysis bag (estimate), + # lower back pain - 2400mg aspirin daily (2400*30.5), CIHD - 75mg aspirin daily (75*30.5) + dose = {'diabetes': 30_500, + 'hypertension': 610, + 'chronic_kidney_disease': 1, + 'chronic_lower_back_pain': 73_200, + 'chronic_ischemic_hd': 2288, + 'ever_stroke': 2288, + 'ever_heart_attack': 2288} + # Check availability of medication for condition if self.get_consumables( - item_codes=self.module.parameters[f'{self.condition}_hsi'].get('medication_item_code').astype(int) - ): + item_codes={self.module.parameters[f'{self.condition}_hsi'].get('medication_item_code').astype(int) + : dose[self.condition]}): # Schedule their next HSI for a refill of medication, one month from now self.sim.modules['HealthSystem'].schedule_hsi_event( hsi_event=self, @@ -1734,10 +1758,13 @@ def do_for_each_event_to_be_investigated(self, _ev): df.at[person_id, f'nc_{_ev}_date_diagnosis'] = self.sim.date df.at[person_id, f'nc_{_ev}_ever_diagnosed'] = True if self.module.parameters['prob_care_provided_given_seek_emergency_care'] > self.module.rng.random_sample(): + # If care is provided.... + dose = 20 if _ev == 'ever_stroke' else 40 + if self.get_consumables( - item_codes=self.module.parameters[f'{_ev}_hsi'].get( - 'emergency_medication_item_code').astype(int) + item_codes={self.module.parameters[f'{_ev}_hsi'].get( + 'emergency_medication_item_code').astype(int): dose} ): logger.debug(key='debug', data='Treatment will be provided.') df.at[person_id, f'nc_{_ev}_on_medication'] = True diff --git a/src/tlo/methods/care_of_women_during_pregnancy.py b/src/tlo/methods/care_of_women_during_pregnancy.py index bc22b86993..4025941254 100644 --- a/src/tlo/methods/care_of_women_during_pregnancy.py +++ b/src/tlo/methods/care_of_women_during_pregnancy.py @@ -1,5 +1,6 @@ from pathlib import Path +import numpy as np import pandas as pd from tlo import DateOffset, Module, Parameter, Property, Types, logging @@ -202,157 +203,160 @@ def get_and_store_pregnancy_item_codes(self): This function defines the required consumables for each intervention delivered during this module and stores them in a module level dictionary called within HSIs """ - get_list_of_items = pregnancy_helper_functions.get_list_of_items + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name + # First we store the item codes for the consumables for which their quantity varies for individuals based on + # length of pregnancy # ---------------------------------- BLOOD TEST EQUIPMENT --------------------------------------------------- self.item_codes_preg_consumables['blood_test_equipment'] = \ - get_list_of_items(self, ['Blood collecting tube, 5 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) - + {ic('Blood collecting tube, 5 ml'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } # ---------------------------------- IV DRUG ADMIN EQUIPMENT ------------------------------------------------- self.item_codes_preg_consumables['iv_drug_equipment'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + {ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } # -------------------------------------------- ECTOPIC PREGNANCY --------------------------------------------- self.item_codes_preg_consumables['ectopic_pregnancy_core'] = \ - get_list_of_items(self, ['Halothane (fluothane)_250ml_CMST']) + {ic('Halothane (fluothane)_250ml_CMST'): 100} self.item_codes_preg_consumables['ectopic_pregnancy_optional'] = \ - get_list_of_items(self, ['Scalpel blade size 22 (individually wrapped)_100_CMST', - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Paracetamol, tablet, 500 mg', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Suture pack', - 'Gauze, absorbent 90cm x 40m_each_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box' - ]) + {ic('Scalpel blade size 22 (individually wrapped)_100_CMST'): 1, + ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Pethidine, 50 mg/ml, 2 ml ampoule'): 6, + ic('Suture pack'): 1, + ic('Gauze, absorbent 90cm x 40m_each_CMST'): 30, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + } # ------------------------------------------- POST ABORTION CARE - GENERAL ----------------------------------- self.item_codes_preg_consumables['post_abortion_care_core'] = \ - get_list_of_items(self, ['Misoprostol, tablet, 200 mcg']) + {ic('Misoprostol, tablet, 200 mcg'): 600} self.item_codes_preg_consumables['post_abortion_care_optional'] = \ - get_list_of_items(self, ['Complete blood count', - 'Blood collecting tube, 5 ml', - 'Paracetamol, tablet, 500 mg', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box' - ]) + {ic('Complete blood count'): 1, + ic('Blood collecting tube, 5 ml'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Gauze, absorbent 90cm x 40m_each_CMST'): 30, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + } # ------------------------------------------- POST ABORTION CARE - SEPSIS ------------------------------------- self.item_codes_preg_consumables['post_abortion_care_sepsis_core'] = \ - get_list_of_items(self, ['Benzylpenicillin 3g (5MU), PFR_each_CMST', - 'Gentamycin, injection, 40 mg/ml in 2 ml vial']) + {ic('Benzathine benzylpenicillin, powder for injection, 2.4 million IU'): 8, + ic('Gentamycin, injection, 40 mg/ml in 2 ml vial'): 6, + } self.item_codes_preg_consumables['post_abortion_care_sepsis_optional'] = \ - get_list_of_items(self, ['Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Oxygen, 1000 liters, primarily with oxygen cylinders']) - - # ------------------------------------------- POST ABORTION CARE - SHOCK ------------------------------------- + {ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + } + + # ------------------------------------------- POST ABORTION CARE - SHOCK ------------------------------------ self.item_codes_preg_consumables['post_abortion_care_shock'] = \ - get_list_of_items(self, ['Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Oxygen, 1000 liters, primarily with oxygen cylinders']) + {ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + } self.item_codes_preg_consumables['post_abortion_care_shock_optional'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Giving set iv administration + needle 15 drops/ml_each_CMST']) - + {ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + } # ---------------------------------- URINE DIPSTICK ---------------------------------------------------------- - self.item_codes_preg_consumables['urine_dipstick'] = get_list_of_items(self, ['Urine analysis']) + self.item_codes_preg_consumables['urine_dipstick'] = {ic('Urine analysis'): 1} # ---------------------------------- IRON AND FOLIC ACID ------------------------------------------------------ - self.item_codes_preg_consumables['iron_folic_acid'] = get_list_of_items( - self, ['Ferrous Salt + Folic Acid, tablet, 200 + 0.25 mg']) + # Dose changes at run time + self.item_codes_preg_consumables['iron_folic_acid'] = \ + {ic('Ferrous Salt + Folic Acid, tablet, 200 + 0.25 mg'): 1} # TODO: update con requested here # --------------------------------- BALANCED ENERGY AND PROTEIN ---------------------------------------------- - self.item_codes_preg_consumables['balanced_energy_protein'] = get_list_of_items( - self, ['Dietary supplements (country-specific)']) + # Dose changes at run time + self.item_codes_preg_consumables['balanced_energy_protein'] = \ + {ic('Dietary supplements (country-specific)'): 1} # --------------------------------- INSECTICIDE TREATED NETS ------------------------------------------------ - self.item_codes_preg_consumables['itn'] = get_list_of_items(self, ['Insecticide-treated net']) + self.item_codes_preg_consumables['itn'] = {ic('Insecticide-treated net'): 1} # --------------------------------- CALCIUM SUPPLEMENTS ----------------------------------------------------- - self.item_codes_preg_consumables['calcium'] = get_list_of_items(self, ['Calcium, tablet, 600 mg']) + self.item_codes_preg_consumables['calcium'] = {ic('Calcium, tablet, 600 mg'): 1} # -------------------------------- HAEMOGLOBIN TESTING ------------------------------------------------------- - self.item_codes_preg_consumables['hb_test'] = get_list_of_items(self, ['Haemoglobin test (HB)']) + self.item_codes_preg_consumables['hb_test'] = {ic('Haemoglobin test (HB)'): 1} # ------------------------------------------- ALBENDAZOLE ----------------------------------------------------- - self.item_codes_preg_consumables['albendazole'] = get_list_of_items(self, ['Albendazole 200mg_1000_CMST']) + self.item_codes_preg_consumables['albendazole'] = {ic('Albendazole 200mg_1000_CMST'): 400} # ------------------------------------------- HEP B TESTING --------------------------------------------------- - self.item_codes_preg_consumables['hep_b_test'] = get_list_of_items( - self, ['Hepatitis B test kit-Dertemine_100 tests_CMST']) + self.item_codes_preg_consumables['hep_b_test'] = {ic('Hepatitis B test kit-Dertemine_100 tests_CMST'): 1} # ------------------------------------------- SYPHILIS TESTING ------------------------------------------------ - self.item_codes_preg_consumables['syphilis_test'] = get_list_of_items( - self, ['Test, Rapid plasma reagin (RPR)']) + self.item_codes_preg_consumables['syphilis_test'] = {ic('Test, Rapid plasma reagin (RPR)'): 1} # ------------------------------------------- SYPHILIS TREATMENT ---------------------------------------------- - self.item_codes_preg_consumables['syphilis_treatment'] = get_list_of_items( - self, ['Benzathine benzylpenicillin, powder for injection, 2.4 million IU']) - - # ----------------------------------------------- IPTP -------------------------------------------------------- - self.item_codes_preg_consumables['iptp'] = get_list_of_items( - self, ['Sulfamethoxazole + trimethropin, tablet 400 mg + 80 mg']) + self.item_codes_preg_consumables['syphilis_treatment'] =\ + {ic('Benzathine benzylpenicillin, powder for injection, 2.4 million IU'): 1} # ----------------------------------------------- GDM TEST ---------------------------------------------------- - self.item_codes_preg_consumables['gdm_test'] = get_list_of_items(self, ['Blood glucose level test']) + self.item_codes_preg_consumables['gdm_test'] = {ic('Blood glucose level test'): 1} # ------------------------------------------ FULL BLOOD COUNT ------------------------------------------------- - self.item_codes_preg_consumables['full_blood_count'] = get_list_of_items(self, ['Complete blood count']) + self.item_codes_preg_consumables['full_blood_count'] = {ic('Complete blood count'): 1} # ---------------------------------------- BLOOD TRANSFUSION ------------------------------------------------- - self.item_codes_preg_consumables['blood_transfusion'] = get_list_of_items(self, ['Blood, one unit']) + self.item_codes_preg_consumables['blood_transfusion'] = {ic('Blood, one unit'): 2} # --------------------------------------- ORAL ANTIHYPERTENSIVES --------------------------------------------- - self.item_codes_preg_consumables['oral_antihypertensives'] = get_list_of_items( - self, ['Methyldopa 250mg_1000_CMST']) + # Dose changes at run time + self.item_codes_preg_consumables['oral_antihypertensives'] = {ic('Methyldopa 250mg_1000_CMST'): 1} # ------------------------------------- INTRAVENOUS ANTIHYPERTENSIVES --------------------------------------- - self.item_codes_preg_consumables['iv_antihypertensives'] = get_list_of_items( - self, ['Hydralazine, powder for injection, 20 mg ampoule']) + self.item_codes_preg_consumables['iv_antihypertensives'] = \ + {ic('Hydralazine, powder for injection, 20 mg ampoule'): 1} # ---------------------------------------- MAGNESIUM SULPHATE ------------------------------------------------ - self.item_codes_preg_consumables['magnesium_sulfate'] = get_list_of_items( - self, ['Magnesium sulfate, injection, 500 mg/ml in 10-ml ampoule']) + self.item_codes_preg_consumables['magnesium_sulfate'] = \ + {ic('Magnesium sulfate, injection, 500 mg/ml in 10-ml ampoule'): 2} # ---------------------------------------- MANAGEMENT OF ECLAMPSIA -------------------------------------------- - self.item_codes_preg_consumables['eclampsia_management_optional'] = get_list_of_items( - self, ['Misoprostol, tablet, 200 mcg', - 'Oxytocin, injection, 10 IU in 1 ml ampoule', - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Oxygen, 1000 liters, primarily with oxygen cylinders', - 'Complete blood count', - 'Blood collecting tube, 5 ml', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml']) + self.item_codes_preg_consumables['eclampsia_management_optional'] = \ + {ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + ic('Complete blood count'): 1, + ic('Blood collecting tube, 5 ml'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + } # -------------------------------------- ANTIBIOTICS FOR PROM ------------------------------------------------ - self.item_codes_preg_consumables['abx_for_prom'] = get_list_of_items( - self, ['Benzathine benzylpenicillin, powder for injection, 2.4 million IU']) + self.item_codes_preg_consumables['abx_for_prom'] = \ + {ic('Benzathine benzylpenicillin, powder for injection, 2.4 million IU'): 8} # ----------------------------------- ORAL DIABETIC MANAGEMENT ----------------------------------------------- - self.item_codes_preg_consumables['oral_diabetic_treatment'] = get_list_of_items( - self, ['Glibenclamide 5mg_1000_CMST']) + # Dose changes at run time + self.item_codes_preg_consumables['oral_diabetic_treatment'] = \ + {ic('Glibenclamide 5mg_1000_CMST'): 1} # ---------------------------------------- INSULIN ---------------------------------------------------------- - self.item_codes_preg_consumables['insulin_treatment'] = get_list_of_items( - self, ['Insulin soluble 100 IU/ml, 10ml_each_CMST']) + # Dose changes at run time + self.item_codes_preg_consumables['insulin_treatment'] = \ + {ic('Insulin soluble 100 IU/ml, 10ml_each_CMST'): 1} def initialise_simulation(self, sim): @@ -730,7 +734,7 @@ def screening_interventions_delivered_at_every_contact(self, hsi_event): # check consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='urine_dipstick') + self, hsi_event, cons=self.item_codes_preg_consumables['urine_dipstick'], opt_cons=None) # If the intervention will be delivered the dx_manager runs, returning True if the consumables are # available and the test detects protein in the urine @@ -788,8 +792,10 @@ def iron_and_folic_acid_supplementation(self, hsi_event): # check consumable availability - dose is total days of pregnancy x 2 tablets days = self.get_approx_days_of_pregnancy(person_id) + updated_cons = {k: v*(days*2) for (k, v) in self.item_codes_preg_consumables['iron_folic_acid'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='iron_folic_acid', number=days*3) + self, hsi_event, cons=updated_cons, opt_cons=None) if avail: logger.info(key='anc_interventions', data={'mother': person_id, 'intervention': 'iron_folic_acid'}) @@ -822,8 +828,11 @@ def balance_energy_and_protein_supplementation(self, hsi_event): # If the consumables are available... days = self.get_approx_days_of_pregnancy(person_id) + updated_cons = {k: v*days for (k, v) in + self.item_codes_preg_consumables['balanced_energy_protein'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='balanced_energy_protein', number=days) + self, hsi_event, cons=updated_cons, opt_cons=None) # And she is deemed to be at risk (i.e. BMI < 18) she is started on supplements if avail and (df.at[person_id, 'li_bmi'] == 1): @@ -885,8 +894,11 @@ def calcium_supplementation(self, hsi_event): or (df.at[person_id, 'la_parity'] > 4)): days = self.get_approx_days_of_pregnancy(person_id) * 3 + updated_cons = {k: v * days for (k, v) in + self.item_codes_preg_consumables['calcium'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='calcium', number=days) + self, hsi_event, cons=updated_cons, opt_cons=None) if avail: df.at[person_id, 'ac_receiving_calcium_supplements'] = True @@ -909,7 +921,9 @@ def point_of_care_hb_testing(self, hsi_event): # Run check against probability of testing being delivered avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='hb_test', optional='blood_test_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['hb_test'], + opt_cons=self.item_codes_preg_consumables['blood_test_equipment']) # We run the test through the dx_manager and if a woman has anaemia and its detected she will be admitted # for further care @@ -983,8 +997,9 @@ def syphilis_screening_and_treatment(self, hsi_event): logger.info(key='anc_interventions', data={'mother': person_id, 'intervention': 'syphilis_test'}) avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='syphilis_test', - optional='blood_test_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['syphilis_test'], + opt_cons=self.item_codes_preg_consumables['blood_test_equipment']) test = self.sim.modules['HealthSystem'].dx_manager.run_dx_test( dx_tests_to_run='blood_test_syphilis', hsi_event=hsi_event) @@ -993,8 +1008,9 @@ def syphilis_screening_and_treatment(self, hsi_event): if avail and test: avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='syphilis_treatment', - optional='blood_test_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['syphilis_treatment'], + opt_cons=self.item_codes_preg_consumables['blood_test_equipment']) if avail: # We assume that treatment is 100% effective at curing infection @@ -1059,7 +1075,9 @@ def gdm_screening(self, hsi_event): if self.rng.random_sample() < params['prob_intervention_delivered_gdm_test']: avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='gdm_test', optional='blood_test_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['gdm_test'], + opt_cons=self.item_codes_preg_consumables['blood_test_equipment']) # If the test accurately detects a woman has gestational diabetes the consumables are recorded and # she is referred for treatment @@ -1225,8 +1243,9 @@ def antenatal_blood_transfusion(self, individual_id, hsi_event): # Check for consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='blood_transfusion', number=2, - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['blood_transfusion'], + opt_cons=self.item_codes_preg_consumables['iv_drug_equipment']) sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.sim.modules['Labour'], sf='blood_tran', @@ -1253,9 +1272,12 @@ def initiate_maintenance_anti_hypertensive_treatment(self, individual_id, hsi_ev df = self.sim.population.props # Calculate the approximate dose for the remainder of pregnancy and check availability + days = self.get_approx_days_of_pregnancy(individual_id) * 4 + updated_cons = {k: v * days for (k, v) in + self.item_codes_preg_consumables['oral_antihypertensives'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='oral_antihypertensives', - number=(self.get_approx_days_of_pregnancy(individual_id) * 4)) + self, hsi_event, cons=updated_cons, opt_cons=None) # If the consumables are available then the woman is started on treatment if avail: @@ -1274,8 +1296,9 @@ def initiate_treatment_for_severe_hypertension(self, individual_id, hsi_event): # Define the consumables and check their availability avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='iv_antihypertensives', - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['iv_antihypertensives'], + opt_cons=self.item_codes_preg_consumables['iv_drug_equipment']) # If they are available then the woman is started on treatment if avail: @@ -1305,8 +1328,9 @@ def treatment_for_severe_pre_eclampsia_or_eclampsia(self, individual_id, hsi_eve df = self.sim.population.props avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='magnesium_sulfate', - optional='eclampsia_management_optional') + self, hsi_event, + cons=self.item_codes_preg_consumables['magnesium_sulfate'], + opt_cons=self.item_codes_preg_consumables['eclampsia_management_optional']) # check HCW will deliver intervention sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.sim.modules['Labour'], @@ -1329,8 +1353,9 @@ def antibiotics_for_prom(self, individual_id, hsi_event): # check consumables and whether HCW are available to deliver the intervention avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_preg_consumables, core='abx_for_prom', - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_preg_consumables['abx_for_prom'], + opt_cons=self.item_codes_preg_consumables['iv_drug_equipment']) sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.sim.modules['Labour'], sf='iv_abx', @@ -2426,6 +2451,8 @@ def apply(self, person_id, squeeze_factor): if not mother.la_currently_in_labour and not mother.hs_is_inpatient and mother.ps_gest_diab != 'none' \ and (mother.ac_gest_diab_on_treatment != 'none') and (mother.ps_gestational_age_in_weeks > 21): + est_length_preg = self.module.get_approx_days_of_pregnancy(person_id) + def schedule_gdm_event_and_checkup(): # Schedule GestationalDiabetesGlycaemicControlEvent which determines if this new treatment will # effectively control blood glucose prior to next follow up @@ -2450,9 +2477,12 @@ def schedule_gdm_event_and_checkup(): # meds if mother.ac_gest_diab_on_treatment == 'diet_exercise': + days = est_length_preg * 10 + updated_cons = {k: v * days for (k, v) in + self.module.item_codes_preg_consumables['oral_diabetic_treatment'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='oral_diabetic_treatment', - number=(self.module.get_approx_days_of_pregnancy(person_id) * 2)) + self.module, self, cons=updated_cons, opt_cons=None) # If the meds are available women are started on that treatment if avail: @@ -2468,9 +2498,15 @@ def schedule_gdm_event_and_checkup(): # blood sugar- they are started on insulin if mother.ac_gest_diab_on_treatment == 'orals': + # Dose is (avg.) 0.8 units per KG per day. Average weight is an appoximation + required_units_per_preg = 65 * (0.8 * est_length_preg) + required_vials = np.ceil(required_units_per_preg/1000) + + updated_cons = {k: v * required_vials for (k, v) in + self.module.item_codes_preg_consumables['insulin_treatment'].items()} + avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='insulin_treatment', - number=5) + self.module, self, cons=updated_cons, opt_cons=None) if avail: df.at[person_id, 'ac_gest_diab_on_treatment'] = 'insulin' @@ -2514,8 +2550,9 @@ def apply(self, person_id, squeeze_factor): # Request baseline PAC consumables baseline_cons = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='post_abortion_care_core', - optional='post_abortion_care_optional') + self.module, self, + cons=self.module.item_codes_preg_consumables['post_abortion_care_core'], + opt_cons=self.module.item_codes_preg_consumables['post_abortion_care_optional']) # Check HCW availability to deliver surgical removal of retained products sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.sim.modules['Labour'], @@ -2528,29 +2565,32 @@ def apply(self, person_id, squeeze_factor): if abortion_complications.has_any([person_id], 'sepsis', first=True): cons_for_sepsis_pac = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='post_abortion_care_sepsis_core', - optional='post_abortion_care_sepsis_optional') + self.module, self, + cons=self.module.item_codes_preg_consumables['post_abortion_care_sepsis_core'], + opt_cons=self.module.item_codes_preg_consumables['post_abortion_care_sepsis_optional']) if cons_for_sepsis_pac and (baseline_cons or sf_check): df.at[person_id, 'ac_received_post_abortion_care'] = True elif abortion_complications.has_any([person_id], 'haemorrhage', first=True): - cons_for_haemorrhage = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='blood_transfusion', number=2, - optional='iv_drug_equipment') + self.module, self, + cons=self.module.item_codes_preg_consumables['blood_transfusion'], + opt_cons=self.module.item_codes_preg_consumables['iv_drug_equipment']) cons_for_shock = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='post_abortion_care_shock', - optional='post_abortion_care_shock_optional') + self.module, self, + cons=self.module.item_codes_preg_consumables['post_abortion_care_shock'], + opt_cons=self.module.item_codes_preg_consumables['post_abortion_care_shock_optional']) if cons_for_haemorrhage and cons_for_shock and (baseline_cons or sf_check): df.at[person_id, 'ac_received_post_abortion_care'] = True elif abortion_complications.has_any([person_id], 'injury', first=True): cons_for_shock = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='post_abortion_care_shock', - optional='post_abortion_care_shock_optional') + self.module, self, + cons=self.module.item_codes_preg_consumables['post_abortion_care_shock'], + opt_cons=self.module.item_codes_preg_consumables['post_abortion_care_shock_optional']) if cons_for_shock and (baseline_cons or sf_check): df.at[person_id, 'ac_received_post_abortion_care'] = True @@ -2595,8 +2635,9 @@ def apply(self, person_id, squeeze_factor): # We define the required consumables and check their availability avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_preg_consumables, core='ectopic_pregnancy_core', - optional='ectopic_pregnancy_optional') + self.module, self, + cons=self.module.item_codes_preg_consumables['ectopic_pregnancy_core'], + opt_cons=self.module.item_codes_preg_consumables['ectopic_pregnancy_optional']) # If they are available then treatment can go ahead if avail: diff --git a/src/tlo/methods/contraception.py b/src/tlo/methods/contraception.py index 67d6684fce..580125f7ba 100644 --- a/src/tlo/methods/contraception.py +++ b/src/tlo/methods/contraception.py @@ -646,23 +646,60 @@ def select_contraceptive_following_birth(self, mother_id, mother_age): def get_item_code_for_each_contraceptive(self): """Get the item_code for each contraceptive and for contraceptive initiation.""" - # TODO: update with optional items (currently all considered essential) - get_items_from_pkg = self.sim.modules['HealthSystem'].get_item_codes_from_package_name + # ### Get item codes from item names and define number of units per case here + get_item_code = self.sim.modules['HealthSystem'].get_item_code_from_item_name _cons_codes = dict() - # items for each method that requires an HSI to switch to - _cons_codes['pill'] = get_items_from_pkg('Pill') - _cons_codes['male_condom'] = get_items_from_pkg('Male condom') - _cons_codes['other_modern'] = get_items_from_pkg('Female Condom') - # NB. The consumable female condom is used for the contraceptive state of "other_modern method" - _cons_codes['IUD'] = get_items_from_pkg('IUD') - _cons_codes['injections'] = get_items_from_pkg('Injectable') - _cons_codes['implant'] = get_items_from_pkg('Implant') - _cons_codes['female_sterilization'] = get_items_from_pkg('Female sterilization') + # # items for each method that requires an HSI to switch to + # in 80% cases combined pills administrated + # in other 20% cases same amount of progesterone-only pills ("Levonorgestrel 0.0375 mg, cycle") administrated + # (omitted in here) + _cons_codes['pill'] = \ + {get_item_code("Levonorgestrel 0.15 mg + Ethinyl estradiol 30 mcg (Microgynon), cycle"): 21 * 3.75} + _cons_codes['male_condom'] =\ + {get_item_code("Condom, male"): 30} + _cons_codes['other_modern'] =\ + {get_item_code("Female Condom_Each_CMST"): 30} + _cons_codes['IUD'] =\ + {get_item_code("Glove disposable powdered latex medium_100_CMST"): 2, + get_item_code("IUD, Copper T-380A"): 1} + _cons_codes['injections'] = \ + {get_item_code("Depot-Medroxyprogesterone Acetate 150 mg - 3 monthly"): 1, + get_item_code("Glove disposable powdered latex medium_100_CMST"): 1, + get_item_code("Water for injection, 10ml_Each_CMST"): 1, + get_item_code("Povidone iodine, solution, 10 %, 5 ml per injection"): 5, + get_item_code("Gauze, swabs 8-ply 10cm x 10cm_100_CMST"): 1} + _cons_codes['implant'] =\ + {get_item_code("Glove disposable powdered latex medium_100_CMST"): 3, + get_item_code("Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml"): 2, + get_item_code("Povidone iodine, solution, 10 %, 5 ml per injection"): 1*5, # unit: 1 ml + get_item_code("Syringe, needle + swab"): 2, + get_item_code("Trocar"): 1, + get_item_code("Needle suture intestinal round bodied ½ circle trocar_6_CMST"): 1, + # in 50% cases Jadelle administrated + # in other 50% cases other type of implant ("Implanon (Etonogestrel 68 mg)") administrated + # (omitted in here) + get_item_code("Jadelle (implant), box of 2_CMST"): 1, + get_item_code("Gauze, swabs 8-ply 10cm x 10cm_100_CMST"): 1} + _cons_codes['female_sterilization'] =\ + {get_item_code("Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml"): 1, + get_item_code("Atropine sulphate 600 micrograms/ml, 1ml_each_CMST"): 0.5, # 1 unit used only in 50% cases + # approximated by 0.5 unit each time + get_item_code("Diazepam, injection, 5 mg/ml, in 2 ml ampoule"): 1, + get_item_code("Syringe, autodestruct, 5ml, disposable, hypoluer with 21g needle_each_CMST"): 3, + get_item_code("Gauze, swabs 8-ply 10cm x 10cm_100_CMST"): 2, + get_item_code("Needle, suture, assorted sizes, round body"): 3, + get_item_code("Suture, catgut, chromic, 0, 150 cm"): 3, + get_item_code("Tape, adhesive, 2.5 cm wide, zinc oxide, 5 m roll"): 125, # unit: 1 cm long (2.5 cm wide) + get_item_code("Glove surgeon's size 7 sterile_2_CMST"): 2, + get_item_code("Paracetamol, tablet, 500 mg"): 8*500, # unit: 1 mg + get_item_code("Povidone iodine, solution, 10 %, 5 ml per injection"): 2*5, # unit: 1 ml + get_item_code("Cotton wool, 500g_1_CMST"): 100} # unit: 1 g + assert set(_cons_codes.keys()) == set(self.states_that_may_require_HSI_to_switch_to) # items used when initiating a modern reliable method after not using or switching from non-reliable method - _cons_codes['co_initiation'] = get_items_from_pkg('Contraception initiation') + _cons_codes['co_initiation'] = {get_item_code('Pregnancy slide test kit_100_CMST'): 1} return _cons_codes @@ -1145,7 +1182,6 @@ def apply(self, person_id, squeeze_factor): self.sim.population.props.at[person_id, "co_date_of_last_fp_appt"] = self.sim.date # Determine essential and optional items - # TODO: we don't distinguish essential X optional for contraception methods yet, will need to update once we do items_essential = self.module.cons_codes[self.new_contraceptive] items_optional = {} # Record use of consumables and default the person to "not_using" if the consumable is not available. diff --git a/src/tlo/methods/copd.py b/src/tlo/methods/copd.py index 7e85e57ee2..a39e263280 100644 --- a/src/tlo/methods/copd.py +++ b/src/tlo/methods/copd.py @@ -33,7 +33,7 @@ class Copd(Module): """The module responsible for determining Chronic Obstructive Pulmonary Diseases (COPD) status and outcomes. and initialises parameters and properties associated with COPD plus functions and events related to COPD.""" - INIT_DEPENDENCIES = {'SymptomManager', 'Lifestyle'} + INIT_DEPENDENCIES = {'SymptomManager', 'Lifestyle', 'HealthSystem'} ADDITIONAL_DEPENDENCIES = set() METADATA = { @@ -190,14 +190,14 @@ def define_symptoms(self): def lookup_item_codes(self): """Look-up the item-codes for the consumables needed in the HSI Events for this module.""" - # todo: Need to look-up these item-codes. + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name + self.item_codes = { - 'bronchodilater_inhaler': 293, - 'steroid_inhaler': 294, - 'oxygen': 127, - 'aminophylline': 292, - 'amoxycillin': 125, - 'prednisolone': 291 + 'bronchodilater_inhaler': ic('Salbutamol Inhaler 100mcg/dose - 200 doses '), + 'oxygen': ic('Oxygen, 1000 liters, primarily with oxygen cylinders'), + 'aminophylline': ic('Aminophylline 100mg, tablets'), + 'amoxycillin': ic('Amoxycillin 250mg_1000_CMST'), + 'prednisolone': ic('Prednisolone 5mg_100_CMST'), } def do_logging(self): @@ -225,10 +225,9 @@ def _common_first_appt( if ('breathless_moderate' in symptoms) or ('breathless_severe' in symptoms): patient_details_updates = {} # Give inhaler if patient does not already have one - if not patient_details.ch_has_inhaler and consumables_checker( - self.item_codes["bronchodilater_inhaler"] - ): - patient_details_updates["ch_has_inhaler"] = True + if not patient_details.ch_has_inhaler: + if consumables_checker({self.item_codes["bronchodilater_inhaler"]: 1}): + patient_details_updates["ch_has_inhaler"] = True if "breathless_severe" in symptoms: event = HSI_Copd_TreatmentOnSevereExacerbation( @@ -571,7 +570,8 @@ def apply(self, person_id, squeeze_factor): * Provide treatment: whatever is available at this facility at this time (no referral). """ df = self.sim.population.props - if not self.get_consumables(self.module.item_codes['oxygen']): + # Assume average 8L O2 for 2 days inpatient care + if not self.get_consumables({self.module.item_codes['oxygen']: 23_040}): # refer to the next higher facility if the current facility has no oxygen self.facility_levels_index += 1 if self.facility_levels_index >= len(self.all_facility_levels): @@ -581,10 +581,11 @@ def apply(self, person_id, squeeze_factor): else: # Give oxygen and AminoPhylline, if possible, ... and cancel death if the treatment is successful. + # Aminophylline dose = 100mg 8hrly, assuming 600mg in 48 hours prob_treatment_success = self.module.models.prob_livesaved_given_treatment( df=df.iloc[[person_id]], - oxygen=self.get_consumables(self.module.item_codes['oxygen']), - aminophylline=self.get_consumables(self.module.item_codes['aminophylline']) + oxygen=self.get_consumables({self.module.item_codes['oxygen']: 23_040}), + aminophylline=self.get_consumables({self.module.item_codes['aminophylline']: 600}) ) if prob_treatment_success: diff --git a/src/tlo/methods/depression.py b/src/tlo/methods/depression.py index c7f2577382..ef1e4f8cc7 100644 --- a/src/tlo/methods/depression.py +++ b/src/tlo/methods/depression.py @@ -953,9 +953,10 @@ def apply(self, person_id, squeeze_factor): "receiving an HSI. " # Check availability of antidepressant medication - item_code = self.module.parameters['anti_depressant_medication_item_code'] + # Dose is 25mg daily, patient provided with month supply - 25mg x 30.437 (days) = 761mg per month + item_code_with_dose = {self.module.parameters['anti_depressant_medication_item_code']: 761} - if self.get_consumables(item_codes=item_code): + if self.get_consumables(item_codes=item_code_with_dose): # If medication is available, flag as being on antidepressants df.at[person_id, 'de_on_antidepr'] = True @@ -996,7 +997,10 @@ def apply(self, person_id, squeeze_factor): return self.sim.modules['HealthSystem'].get_blank_appt_footprint() # Check availability of antidepressant medication - if self.get_consumables(self.module.parameters['anti_depressant_medication_item_code']): + # Dose is 25mg daily, patient provided with month supply - 25mg x 30.437 (days) = 761mg per month + item_code_with_dose = {self.module.parameters['anti_depressant_medication_item_code']: 761} + + if self.get_consumables(item_codes=item_code_with_dose): # Schedule their next HSI for a refill of medication, one month from now self.sim.modules['HealthSystem'].schedule_hsi_event( hsi_event=HSI_Depression_Refill_Antidepressant(person_id=person_id, module=self.module), diff --git a/src/tlo/methods/diarrhoea.py b/src/tlo/methods/diarrhoea.py index fda4489fe1..cc589475d5 100644 --- a/src/tlo/methods/diarrhoea.py +++ b/src/tlo/methods/diarrhoea.py @@ -651,18 +651,23 @@ def report_daly_values(self): def look_up_consumables(self): """Look up and store the consumables item codes used in each of the HSI.""" - get_item_codes_from_package_name = self.sim.modules['HealthSystem'].get_item_codes_from_package_name - - self.consumables_used_in_hsi['ORS'] = get_item_codes_from_package_name( - package='ORS') - self.consumables_used_in_hsi['Treatment_Severe_Dehydration'] = get_item_codes_from_package_name( - package='Treatment of severe diarrhea') - self.consumables_used_in_hsi['Zinc_Under6mo'] = get_item_codes_from_package_name( - package='Zinc for Children 0-6 months') - self.consumables_used_in_hsi['Zinc_Over6mo'] = get_item_codes_from_package_name( - package='Zinc for Children 6-59 months') - self.consumables_used_in_hsi['Antibiotics_for_Dysentery'] = get_item_codes_from_package_name( - package='Antibiotics for treatment of dysentery') + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name + + self.consumables_used_in_hsi['ORS'] = {ic('ORS, sachet'): 2} + + self.consumables_used_in_hsi['Treatment_Severe_Dehydration'] = \ + {ic('ORS, sachet'): 2, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1000} + + self.consumables_used_in_hsi['Zinc'] = ic('Zinc, tablet, 20 mg') + + # For weight based treatment for children under five, we've averaged the median weight for each for years + # 0-5 as 12kg. + # So for cipro/para - 10mg/kg 12 hrly for 7 days = ((10*12)*2) * 7 (same dose in mg reccomended) + self.consumables_used_in_hsi['Antibiotics_for_Dysentery'] = \ + {ic('Ciprofloxacin 250mg_100_CMST'): 1680, + ic("Paracetamol syrup 120mg/5ml_0.0119047619047619_CMST"): 70} # 24mg/ml so 1680/24 = 70ml per dose def do_treatment(self, person_id, hsi_event): """Method called by the HSI that enacts decisions about a treatment and its effect for diarrhoea caused by a @@ -706,9 +711,10 @@ def do_treatment(self, person_id, hsi_event): # ** Implement the procedure for treatment ** # STEP ZERO: Get the Zinc consumable (happens irrespective of whether child will die or not) + # Dose is 10mg 24hrly for 10 days <6months or 20m for >6mnths + dose = 100 if person.age_exact_years < 0.5 else 200 gets_zinc = hsi_event.get_consumables( - item_codes=self.consumables_used_in_hsi[ - 'Zinc_Under6mo' if person.age_exact_years < 0.5 else 'Zinc_Over6mo'] + item_codes={self.consumables_used_in_hsi['Zinc']: dose} ) # STEP ONE: Aim to alleviate dehydration: @@ -965,7 +971,7 @@ def do_at_generic_first_appt( self.rng.rand() < self.parameters["prob_hospitalization_on_danger_signs"] ) hsi_event_class = ( - HSI_Diarrhoea_Treatment_Inpatient if is_inpatient else + HSI_Diarrhoea_Treatment_Inpatient if is_inpatient else HSI_Diarrhoea_Treatment_Outpatient ) event = hsi_event_class(person_id=patient_id, module=self) diff --git a/src/tlo/methods/epilepsy.py b/src/tlo/methods/epilepsy.py index 6c4ff0e41d..8bc71fb69f 100644 --- a/src/tlo/methods/epilepsy.py +++ b/src/tlo/methods/epilepsy.py @@ -611,7 +611,14 @@ def apply(self, person_id, squeeze_factor): if best_available_medicine is not None: # Request the medicine from the health system - self.get_consumables(self.module.item_codes[best_available_medicine]) + + dose = {'phenobarbitone': 9131, # 100mg per day - 3 months + 'carbamazepine': 91_311, # 1000mg per day - 3 months + 'phenytoin': 27_393} # 300mg per day - 3 months + + self.get_consumables({self.module.item_codes[best_available_medicine]: + dose[best_available_medicine]}) + # Update this person's properties to show that they are currently on medication df.at[person_id, 'ep_antiep'] = True @@ -662,18 +669,30 @@ def apply(self, person_id, squeeze_factor): # Request the medicine best_available_medicine = self.module.get_best_available_medicine(self) if best_available_medicine is not None: + + # Schedule a reoccurrence of this follow-up in 3 months if ep_seiz_stat == '3', + # else, schedule this reoccurrence of it in 1 year (i.e., if ep_seiz_stat == '2' + if df.at[person_id, 'ep_seiz_stat'] == '3': + fu_mnths = 3 + else: + fu_mnths = 12 + # The medicine is available, so request it - self.get_consumables(self.module.item_codes[best_available_medicine]) + dose = {'phenobarbitone_3_mnths': 9131, 'phenobarbitone_12_mnths': 36_525, # 100mg per day - 3/12 months + 'carbamazepine_3_mnths': 91_311, 'carbamazepine_12_mnths': 365_250, # 1000mg per day - 3/12 months + 'phenytoin_3_mnths': 27_393, 'phenytoin_12_mnths': 109_575} # 300mg per day - 3/12 months + + self.get_consumables({self.module.item_codes[best_available_medicine]: + dose[f'{best_available_medicine}_{fu_mnths}_mnths']}) # Reset counter of "failed attempts" and put the appointment for the next occurrence to the usual self._counter_of_failed_attempts_due_to_unavailable_medicines = 0 self.EXPECTED_APPT_FOOTPRINT = self._DEFAULT_APPT_FOOTPRINT - # Schedule a reoccurrence of this follow-up in 3 months if ep_seiz_stat == '3', - # else, schedule this reoccurrence of it in 1 year (i.e., if ep_seiz_stat == '2') + # Schedule follow-up hs.schedule_hsi_event( hsi_event=self, - topen=self.sim.date + DateOffset(months=3 if df.at[person_id, 'ep_seiz_stat'] == '3' else 12), + topen=self.sim.date + DateOffset(months=fu_mnths), tclose=None, priority=0 ) diff --git a/src/tlo/methods/hiv.py b/src/tlo/methods/hiv.py index a132c6e008..fde32ed915 100644 --- a/src/tlo/methods/hiv.py +++ b/src/tlo/methods/hiv.py @@ -1013,31 +1013,37 @@ def initialise_simulation(self, sim): self.item_codes_for_consumables_required['circ'] = \ hs.get_item_codes_from_package_name("Male circumcision ") - self.item_codes_for_consumables_required['prep'] = { - hs.get_item_code_from_item_name("Tenofovir (TDF)/Emtricitabine (FTC), tablet, 300/200 mg"): 1} + # adult prep: 1 tablet daily + self.item_codes_for_consumables_required['prep'] = \ + hs.get_item_code_from_item_name("Tenofovir (TDF)/Emtricitabine (FTC), tablet, 300/200 mg") - # infant NVP given in 3-monthly dosages - self.item_codes_for_consumables_required['infant_prep'] = { - hs.get_item_code_from_item_name("Nevirapine, oral solution, 10 mg/ml"): 1} + # infant NVP 1.5mg daily for birth weight 2500g or above, for 6 weeks + self.item_codes_for_consumables_required['infant_prep'] = \ + hs.get_item_code_from_item_name("Nevirapine, oral solution, 10 mg/ml") # First - line ART for adults(age > "ART_age_cutoff_older_child") - self.item_codes_for_consumables_required['First-line ART regimen: adult'] = { - hs.get_item_code_from_item_name("First-line ART regimen: adult"): 1} - self.item_codes_for_consumables_required['First-line ART regimen: adult: cotrimoxazole'] = { - hs.get_item_code_from_item_name("Cotrimoxizole, 960mg pppy"): 1} + # TDF/3TC/DTG 120/60/50mg, 1 tablet per day + # cotrim adult tablet, 1 tablet per day, units specified in mg * dispensation days + self.item_codes_for_consumables_required['First-line ART regimen: adult'] = \ + hs.get_item_code_from_item_name("First-line ART regimen: adult") + self.item_codes_for_consumables_required['First-line ART regimen: adult: cotrimoxazole'] = \ + hs.get_item_code_from_item_name("Cotrimoxizole, 960mg pppy") # ART for older children aged ("ART_age_cutoff_younger_child" < age <= "ART_age_cutoff_older_child"): - # cotrim is separate item - optional in get_cons call - self.item_codes_for_consumables_required['First line ART regimen: older child'] = { - hs.get_item_code_from_item_name("First line ART regimen: older child"): 1} - self.item_codes_for_consumables_required['First line ART regimen: older child: cotrimoxazole'] = { - hs.get_item_code_from_item_name("Sulfamethoxazole + trimethropin, tablet 400 mg + 80 mg"): 1} + # ABC/3TC/DTG 120/60/50mg, 3 tablets per day + # cotrim paediatric tablet, 4 tablets per day, units specified in mg * dispensation days + self.item_codes_for_consumables_required['First line ART regimen: older child'] = \ + hs.get_item_code_from_item_name("First line ART regimen: older child") + self.item_codes_for_consumables_required['First line ART regimen: older child: cotrimoxazole'] = \ + hs.get_item_code_from_item_name("Cotrimoxazole 120mg_1000_CMST") # ART for younger children aged (age < "ART_age_cutoff_younger_child"): - self.item_codes_for_consumables_required['First line ART regimen: young child'] = { - hs.get_item_code_from_item_name("First line ART regimen: young child"): 1} - self.item_codes_for_consumables_required['First line ART regimen: young child: cotrimoxazole'] = { - hs.get_item_code_from_item_name("Sulfamethoxazole + trimethropin, oral suspension, 240 mg, 100 ml"): 1} + # ABC/3TC/DTG 120/60/10mg, 2 tablets per day + # cotrim paediatric tablet, 2 tablets per day, units specified in mg * dispensation days + self.item_codes_for_consumables_required['First line ART regimen: young child'] = \ + hs.get_item_code_from_item_name("First line ART regimen: young child") + self.item_codes_for_consumables_required['First line ART regimen: young child: cotrimoxazole'] = \ + hs.get_item_code_from_item_name("Cotrimoxazole 120mg_1000_CMST") # 7) Define the DxTests # HIV Rapid Diagnostic Test: @@ -2467,7 +2473,9 @@ def apply(self, person_id, squeeze_factor): return self.sim.modules["HealthSystem"].get_blank_appt_footprint() # Check that infant prophylaxis is available and if it is, initiate: - if self.get_consumables(item_codes=self.module.item_codes_for_consumables_required['infant_prep']): + if self.get_consumables( + item_codes={self.module.item_codes_for_consumables_required['infant_prep']: 63} + ): df.at[person_id, "hv_is_on_prep"] = True # Schedule follow-up visit for 3 months time @@ -2551,7 +2559,10 @@ def apply(self, person_id, squeeze_factor): return self.make_appt_footprint({"Over5OPD": 1, "VCTPositive": 1}) # Check that PrEP is available and if it is, initiate or continue PrEP: - if self.get_consumables(item_codes=self.module.item_codes_for_consumables_required['prep']): + quantity_required = self.module.parameters['dispensation_period_months'] * 30 + if self.get_consumables( + item_codes={self.module.item_codes_for_consumables_required['prep']: quantity_required} + ): df.at[person_id, "hv_is_on_prep"] = True # Schedule 'decision about whether to continue on PrEP' for 3 months time @@ -2792,29 +2803,33 @@ def get_drugs(self, age_of_person): whether individual drugs were available""" p = self.module.parameters + dispensation_days = 30 * self.module.parameters['dispensation_period_months'] if age_of_person < p["ART_age_cutoff_young_child"]: # Formulation for young children drugs_available = self.get_consumables( - item_codes=self.module.item_codes_for_consumables_required['First line ART regimen: young child'], - optional_item_codes=self.module.item_codes_for_consumables_required[ - 'First line ART regimen: young child: cotrimoxazole'], + item_codes={self.module.item_codes_for_consumables_required[ + 'First line ART regimen: young child']: dispensation_days * 2}, + optional_item_codes={self.module.item_codes_for_consumables_required[ + 'First line ART regimen: young child: cotrimoxazole']: dispensation_days * 240}, return_individual_results=True) elif age_of_person <= p["ART_age_cutoff_older_child"]: # Formulation for older children drugs_available = self.get_consumables( - item_codes=self.module.item_codes_for_consumables_required['First line ART regimen: older child'], - optional_item_codes=self.module.item_codes_for_consumables_required[ - 'First line ART regimen: older child: cotrimoxazole'], + item_codes={self.module.item_codes_for_consumables_required[ + 'First line ART regimen: older child']: dispensation_days * 3}, + optional_item_codes={self.module.item_codes_for_consumables_required[ + 'First line ART regimen: older child: cotrimoxazole']: dispensation_days * 480}, return_individual_results=True) else: # Formulation for adults drugs_available = self.get_consumables( - item_codes=self.module.item_codes_for_consumables_required['First-line ART regimen: adult'], - optional_item_codes=self.module.item_codes_for_consumables_required[ - 'First-line ART regimen: adult: cotrimoxazole'], + item_codes={self.module.item_codes_for_consumables_required[ + 'First-line ART regimen: adult']: dispensation_days}, + optional_item_codes={self.module.item_codes_for_consumables_required[ + 'First-line ART regimen: adult: cotrimoxazole']: dispensation_days * 960}, return_individual_results=True) # add drug names to dict diff --git a/src/tlo/methods/labour.py b/src/tlo/methods/labour.py index dcd8527466..2280d41335 100644 --- a/src/tlo/methods/labour.py +++ b/src/tlo/methods/labour.py @@ -691,174 +691,180 @@ def get_and_store_labour_item_codes(self): This function defines the required consumables for each intervention delivered during this module and stores them in a module level dictionary called within HSIs """ - get_item_code_from_pkg = self.sim.modules['HealthSystem'].get_item_codes_from_package_name - - get_list_of_items = pregnancy_helper_functions.get_list_of_items - - # ---------------------------------- IV DRUG ADMIN EQUIPMENT ------------------------------------------------- - self.item_codes_lab_consumables['iv_drug_equipment'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name # ---------------------------------- BLOOD TEST EQUIPMENT --------------------------------------------------- self.item_codes_lab_consumables['blood_test_equipment'] = \ - get_list_of_items(self, ['Blood collecting tube, 5 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + {ic('Blood collecting tube, 5 ml'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } + # ---------------------------------- IV DRUG ADMIN EQUIPMENT ------------------------------------------------- + self.item_codes_lab_consumables['iv_drug_equipment'] = \ + {ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } # ------------------------------------------ FULL BLOOD COUNT ------------------------------------------------- - self.item_codes_lab_consumables['full_blood_count'] = get_list_of_items(self, ['Complete blood count']) + self.item_codes_lab_consumables['full_blood_count'] = {ic('Complete blood count'): 1} # -------------------------------------------- DELIVERY ------------------------------------------------------ # assuming CDK has blade, soap, cord tie self.item_codes_lab_consumables['delivery_core'] = \ - get_list_of_items(self, ['Clean delivery kit', - 'Chlorhexidine 1.5% solution_5_CMST']) + {ic('Clean delivery kit'): 1, + ic('Chlorhexidine 1.5% solution_5_CMST'): 20, + } self.item_codes_lab_consumables['delivery_optional'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Gauze, absorbent 90cm x 40m_each_CMST', - 'Paracetamol, tablet, 500 mg']) + {ic('Gauze, absorbent 90cm x 40m_each_CMST'): 30, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000 + } # -------------------------------------------- CAESAREAN DELIVERY ------------------------------------------ self.item_codes_lab_consumables['caesarean_delivery_core'] = \ - get_list_of_items(self, ['Halothane (fluothane)_250ml_CMST', - 'Ceftriaxone 1g, PFR_each_CMST', - 'Metronidazole 200mg_1000_CMST']) + {ic('Halothane (fluothane)_250ml_CMST'): 100, + ic('Ceftriaxone 1g, PFR_each_CMST'): 2, + ic('Metronidazole 200mg_1000_CMST'): 1, # todo: replace + } self.item_codes_lab_consumables['caesarean_delivery_optional'] = \ - get_list_of_items(self, ['Scalpel blade size 22 (individually wrapped)_100_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Paracetamol, tablet, 500 mg', - 'Declofenac injection_each_CMST', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml', - "ringer's lactate (Hartmann's solution), 1000 ml_12_IDA", - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - "Giving set iv administration + needle 15 drops/ml_each_CMST", - "Chlorhexidine 1.5% solution_5_CMST"]) + {ic('Scalpel blade size 22 (individually wrapped)_100_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Declofenac injection_each_CMST'): 2, + ic("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, + } # -------------------------------------------- OBSTETRIC SURGERY ---------------------------------------------- self.item_codes_lab_consumables['obstetric_surgery_core'] = \ - get_list_of_items(self, ['Halothane (fluothane)_250ml_CMST', - 'Ceftriaxone 1g, PFR_each_CMST', - 'Metronidazole 200mg_1000_CMST']) + {ic('Halothane (fluothane)_250ml_CMST'): 100, + ic('Ceftriaxone 1g, PFR_each_CMST'): 2, + ic('Metronidazole 200mg_1000_CMST'): 1, # todo: replace + } self.item_codes_lab_consumables['obstetric_surgery_optional'] = \ - get_list_of_items(self, ['Scalpel blade size 22 (individually wrapped)_100_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Paracetamol, tablet, 500 mg', - 'Declofenac injection_each_CMST', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml', - "ringer's lactate (Hartmann's solution), 1000 ml_12_IDA", - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - "Giving set iv administration + needle 15 drops/ml_each_CMST"]) + {ic('Scalpel blade size 22 (individually wrapped)_100_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Declofenac injection_each_CMST'): 2, + ic("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, + } # -------------------------------------------- ABX FOR PROM ------------------------------------------------- self.item_codes_lab_consumables['abx_for_prom'] = \ - get_list_of_items(self, ['Benzathine benzylpenicillin, powder for injection, 2.4 million IU']) + {ic('Benzathine benzylpenicillin, powder for injection, 2.4 million IU'): 8} # -------------------------------------------- ANTENATAL STEROIDS --------------------------------------------- + self.item_codes_lab_consumables['antenatal_steroids'] = \ - get_list_of_items(self, ['Dexamethasone 5mg/ml, 5ml_each_CMST']) + {ic('Dexamethasone 5mg/ml, 5ml_each_CMST'): 12} # ------------------------------------- INTRAVENOUS ANTIHYPERTENSIVES --------------------------------------- self.item_codes_lab_consumables['iv_antihypertensives'] = \ - get_list_of_items(self, ['Hydralazine, powder for injection, 20 mg ampoule']) + {ic('Hydralazine, powder for injection, 20 mg ampoule'): 1} # --------------------------------------- ORAL ANTIHYPERTENSIVES --------------------------------------------- self.item_codes_lab_consumables['oral_antihypertensives'] = \ - get_list_of_items(self, ['Methyldopa 250mg_1000_CMST']) + {ic('Methyldopa 250mg_1000_CMST'): 1} # ---------------------------------- SEVERE PRE-ECLAMPSIA/ECLAMPSIA ----------------------------------------- self.item_codes_lab_consumables['magnesium_sulfate'] = \ - get_list_of_items(self, ['Magnesium sulfate, injection, 500 mg/ml in 10-ml ampoule']) + {ic('Magnesium sulfate, injection, 500 mg/ml in 10-ml ampoule'): 2} self.item_codes_lab_consumables['eclampsia_management_optional'] = \ - get_list_of_items(self, ['Misoprostol, tablet, 200 mcg', - 'Oxytocin, injection, 10 IU in 1 ml ampoule', - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Oxygen, 1000 liters, primarily with oxygen cylinders', - 'Complete blood count', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml']) - + {ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + ic('Complete blood count'): 1, + ic('Blood collecting tube, 5 ml'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + } # ------------------------------------- OBSTRUCTED LABOUR --------------------------------------------------- self.item_codes_lab_consumables['obstructed_labour'] = \ - get_list_of_items(self, ['Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml', - 'Benzylpenicillin 3g (5MU), PFR_each_CMST', - 'Gentamycin, injection, 40 mg/ml in 2 ml vial', - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Complete blood count', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml', - 'Paracetamol, tablet, 500 mg', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Gauze, absorbent 90cm x 40m_each_CMST', - 'Suture pack']) - + {ic('Lidocaine HCl (in dextrose 7.5%), ampoule 2 ml'): 1, + ic('Benzathine benzylpenicillin, powder for injection, 2.4 million IU'): 8, + ic('Gentamycin, injection, 40 mg/ml in 2 ml vial'): 6, + ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Complete blood count'): 1, + ic('Blood collecting tube, 5 ml'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Pethidine, 50 mg/ml, 2 ml ampoule'): 6, + ic('Gauze, absorbent 90cm x 40m_each_CMST'): 30, + ic('Suture pack'): 1, + } # ------------------------------------- OBSTETRIC VACUUM --------------------------------------------------- - self.item_codes_lab_consumables['vacuum'] = get_list_of_items(self, ['Vacuum, obstetric']) + self.item_codes_lab_consumables['vacuum'] = {ic('Vacuum, obstetric'): 1} # ------------------------------------- MATERNAL SEPSIS ----------------------------------------------------- self.item_codes_lab_consumables['maternal_sepsis_core'] = \ - get_list_of_items(self, ['Benzylpenicillin 3g (5MU), PFR_each_CMST', - 'Gentamycin, injection, 40 mg/ml in 2 ml vial']) - # 'Metronidazole, injection, 500 mg in 100 ml vial']) + {ic('Benzylpenicillin 3g (5MU), PFR_each_CMST'): 8, + ic('Gentamycin, injection, 40 mg/ml in 2 ml vial'): 6, + } self.item_codes_lab_consumables['maternal_sepsis_optional'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Oxygen, 1000 liters, primarily with oxygen cylinders', - 'Paracetamol, tablet, 500 mg', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml', - 'Disposables gloves, powder free, 100 pieces per box', - 'Complete blood count']) - + {ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Complete blood count'): 1, + } # ------------------------------------- ACTIVE MANAGEMENT THIRD STAGE --------------------------------------- - self.item_codes_lab_consumables['amtsl'] = \ - get_list_of_items(self, ['Oxytocin, injection, 10 IU in 1 ml ampoule']) + self.item_codes_lab_consumables['amtsl'] = {ic('Oxytocin, injection, 10 IU in 1 ml ampoule'): 1} # ------------------------------------- POSTPARTUM HAEMORRHAGE --------------------------------------- self.item_codes_lab_consumables['pph_core'] = \ - get_list_of_items(self, ['Oxytocin, injection, 10 IU in 1 ml ampoule']) + {ic('Oxytocin, injection, 10 IU in 1 ml ampoule'): 5} self.item_codes_lab_consumables['pph_optional'] = \ - get_list_of_items(self, ['Misoprostol, tablet, 200 mcg', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Oxygen, 1000 liters, primarily with oxygen cylinders', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Bag, urine, collecting, 2000 ml', - 'Foley catheter', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box', - 'Complete blood count']) + {ic('Misoprostol, tablet, 200 mcg'): 600, + ic('Pethidine, 50 mg/ml, 2 ml ampoule'): 6, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 23_040, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1, + ic('Complete blood count'): 1, + } # ------------------------------------- BLOOD TRANSFUSION --------------------------------------- - self.item_codes_lab_consumables['blood_transfusion'] = get_list_of_items(self, ['Blood, one unit']) + self.item_codes_lab_consumables['blood_transfusion'] = {ic('Blood, one unit'): 2} # ------------------------------------------ FULL BLOOD COUNT ------------------------------------------------- - self.item_codes_lab_consumables['hb_test'] = get_list_of_items(self, ['Haemoglobin test (HB)']) + self.item_codes_lab_consumables['hb_test'] = {ic('Haemoglobin test (HB)'): 1} # ---------------------------------- IRON AND FOLIC ACID ------------------------------------------------------ + # Dose changes at run time self.item_codes_lab_consumables['iron_folic_acid'] = \ - get_item_code_from_pkg('Ferrous Salt + Folic Acid, tablet, 200 + 0.25 mg') + {ic('Ferrous Salt + Folic Acid, tablet, 200 + 0.25 mg'): 1} # -------------------------------------------- RESUSCITATION ------------------------------------------ - self.item_codes_lab_consumables['resuscitation'] = \ - get_list_of_items(self, ['Infant resuscitator, clear plastic + mask + bag_each_CMST']) + self.item_codes_lab_consumables['resuscitation'] =\ + {ic('Infant resuscitator, clear plastic + mask + bag_each_CMST'): 1} def initialise_simulation(self, sim): # Update self.current_parameters @@ -1668,7 +1674,9 @@ def prophylactic_labour_interventions(self, hsi_event): # If she has not already receive antibiotics, we check for consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='abx_for_prom', optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_lab_consumables['abx_for_prom'], + opt_cons=self.item_codes_lab_consumables['iv_drug_equipment']) # Then query if these consumables are available during this HSI And provide if available. # Antibiotics for from reduce risk of newborn sepsis within the first @@ -1682,8 +1690,9 @@ def prophylactic_labour_interventions(self, hsi_event): mni[person_id]['labour_state'] == 'late_preterm_labour': avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='antenatal_steroids', - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_lab_consumables['antenatal_steroids'], + opt_cons=self.item_codes_lab_consumables['iv_drug_equipment']) # If available they are given. Antenatal steroids reduce a preterm newborns chance of developing # respiratory distress syndrome and of death associated with prematurity @@ -1745,8 +1754,9 @@ def assessment_and_treatment_of_severe_pre_eclampsia_mgso4(self, hsi_event, labo # Define and check for the required consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='magnesium_sulfate', - optional='eclampsia_management_optional') + self, hsi_event, + cons=self.item_codes_lab_consumables['magnesium_sulfate'], + opt_cons=self.item_codes_lab_consumables['eclampsia_management_optional']) # If the consumables are available - the intervention is delivered. IV magnesium reduces the # probability that a woman with severe pre-eclampsia will experience eclampsia in labour @@ -1774,8 +1784,9 @@ def assessment_and_treatment_of_hypertension(self, hsi_event, labour_stage): # Then query if these consumables are available during this HSI avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='iv_antihypertensives', - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_lab_consumables['iv_antihypertensives'], + opt_cons=self.item_codes_lab_consumables['iv_drug_equipment']) # If they are available then the woman is started on treatment. Intravenous antihypertensive reduce a # womans risk of progression from mild to severe gestational hypertension ANd reduce risk of death for @@ -1789,8 +1800,9 @@ def assessment_and_treatment_of_hypertension(self, hsi_event, labour_stage): elif (labour_stage == 'pp') and (df.at[person_id, 'pn_htn_disorders'] == 'severe_gest_htn'): df.at[person_id, 'pn_htn_disorders'] = 'gest_htn' - avail = hsi_event.get_consumables( - item_codes=self.item_codes_lab_consumables['oral_antihypertensives']) + dose = (7 * 4) * 6 # approximating 4 tablets a day, for 6 weeks + cons = {_i: dose for _i in self.item_codes_lab_consumables['oral_antihypertensives']} + avail = hsi_event.get_consumables(item_codes=cons) if avail: df.at[person_id, 'la_gest_htn_on_treatment'] = True @@ -1821,8 +1833,9 @@ def assessment_and_treatment_of_eclampsia(self, hsi_event, labour_stage): # define and check required consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='magnesium_sulfate', - optional='eclampsia_management_optional') + self, hsi_event, + cons=self.item_codes_lab_consumables['magnesium_sulfate'], + opt_cons=self.item_codes_lab_consumables['eclampsia_management_optional']) if (labour_stage == 'ip') and (df.at[person_id, 'ac_admitted_for_immediate_delivery'] == 'none'): self.determine_delivery_mode_in_spe_or_ec(person_id, hsi_event, 'ec') @@ -1868,8 +1881,9 @@ def refer_for_cs(): # If the general package is available AND the facility has the correct tools to carry out the # delivery then it can occur avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='vacuum', - optional='obstructed_labour') + self, hsi_event, + cons=self.item_codes_lab_consumables['vacuum'], + opt_cons=self.item_codes_lab_consumables['obstructed_labour']) # run HCW check sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self, sf='avd', @@ -1921,8 +1935,9 @@ def assessment_and_treatment_of_maternal_sepsis(self, hsi_event, labour_stage): # Define and check available consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='maternal_sepsis_core', - optional='maternal_sepsis_optional') + self, hsi_event, + cons=self.item_codes_lab_consumables['maternal_sepsis_core'], + opt_cons=self.item_codes_lab_consumables['maternal_sepsis_optional']) # If delivered this intervention reduces a womans risk of dying from sepsis if avail and sf_check: @@ -2000,7 +2015,9 @@ def active_management_of_the_third_stage_of_labour(self, hsi_event): # Define and check available consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='amtsl', optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_lab_consumables['amtsl'], + opt_cons=self.item_codes_lab_consumables['iv_drug_equipment']) # run HCW check sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self, sf='uterotonic', @@ -2031,7 +2048,9 @@ def assessment_and_treatment_of_pph_uterine_atony(self, hsi_event): # Define and check available consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='pph_core', optional='pph_optional') + self, hsi_event, + cons=self.item_codes_lab_consumables['pph_core'], + opt_cons=self.item_codes_lab_consumables['pph_optional']) # run HCW check sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self, sf='uterotonic', @@ -2114,8 +2133,9 @@ def surgical_management_of_pph(self, hsi_event): # We log the required consumables and condition the surgery happening on the availability of the # first consumable in this package, the anaesthetic required for the surgery avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='obstetric_surgery_core', - optional='obstetric_surgery_optional') + self, hsi_event, + cons=self.item_codes_lab_consumables['obstetric_surgery_core'], + opt_cons=self.item_codes_lab_consumables['obstetric_surgery_optional']) # run HCW check sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self, sf='surg', @@ -2150,8 +2170,9 @@ def blood_transfusion(self, hsi_event): # Check consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_lab_consumables, core='blood_transfusion', number=2, - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_lab_consumables['blood_transfusion'], + opt_cons=self.item_codes_lab_consumables['iv_drug_equipment']) # check HCW sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self, sf='blood_tran', @@ -2904,8 +2925,9 @@ def apply(self, person_id, squeeze_factor): # LOG CONSUMABLES FOR DELIVERY... # We assume all deliveries require this basic package of consumables avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_lab_consumables, core='delivery_core', - optional='delivery_optional') + self.module, self, + cons=self.module.item_codes_lab_consumables['delivery_core'], + opt_cons=self.module.item_codes_lab_consumables['delivery_optional']) # If the clean delivery kit consumable is available, we assume women benefit from clean delivery if avail: @@ -2981,7 +3003,7 @@ def apply(self, person_id, squeeze_factor): # TODO: potential issue is that this consumable is being logged now for every birth as opposed to # for each birth where resuscitation of the newborn is required avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_lab_consumables, core='resuscitation') + self.module, self, cons=self.module.item_codes_lab_consumables['resuscitation'], opt_cons=None) # Run HCW check sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.module, @@ -3200,8 +3222,9 @@ def apply(self, person_id, squeeze_factor): # We log the required consumables and condition the caesarean happening on the availability of the # first consumable in this package, the anaesthetic required for the surgery avail = pregnancy_helper_functions.return_cons_avail( - self.module, self, self.module.item_codes_lab_consumables, core='caesarean_delivery_core', - optional='caesarean_delivery_optional') + self.module, self, + cons=self.module.item_codes_lab_consumables['caesarean_delivery_core'], + opt_cons=self.module.item_codes_lab_consumables['caesarean_delivery_optional']) # We check that the HCW will deliver the intervention sf_check = pregnancy_helper_functions.check_emonc_signal_function_will_run(self.module, sf='surg', diff --git a/src/tlo/methods/newborn_outcomes.py b/src/tlo/methods/newborn_outcomes.py index debfdb3530..492c37a1fe 100644 --- a/src/tlo/methods/newborn_outcomes.py +++ b/src/tlo/methods/newborn_outcomes.py @@ -377,43 +377,53 @@ def get_and_store_newborn_item_codes(self): This function defines the required consumables for each intervention delivered during this module and stores them in a module level dictionary called within HSIs """ - get_list_of_items = pregnancy_helper_functions.get_list_of_items - - # ---------------------------------- IV DRUG ADMIN EQUIPMENT ------------------------------------------------- - self.item_codes_nb_consumables['iv_drug_equipment'] = \ - get_list_of_items(self, ['Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name + # First we store the item codes for the consumables for which their quantity varies for individuals based on + # length of pregnancy # ---------------------------------- BLOOD TEST EQUIPMENT --------------------------------------------------- self.item_codes_nb_consumables['blood_test_equipment'] = \ - get_list_of_items(self, ['Disposables gloves, powder free, 100 pieces per box']) + {ic('Blood collecting tube, 5 ml'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } + # ---------------------------------- IV DRUG ADMIN EQUIPMENT ------------------------------------------------- + self.item_codes_nb_consumables['iv_drug_equipment'] = \ + {ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } # -------------------------------------------- VITAMIN K ------------------------------------------ self.item_codes_nb_consumables['vitamin_k'] = \ - get_list_of_items(self, ['vitamin K1 (phytomenadione) 1 mg/ml, 1 ml, inj._100_IDA']) + {ic('vitamin K1 (phytomenadione) 1 mg/ml, 1 ml, inj._100_IDA'): 1} # -------------------------------------------- EYE CARE ------------------------------------------ - self.item_codes_nb_consumables['eye_care'] = get_list_of_items( - self, ['Tetracycline eye ointment, 1 %, tube 5 mg']) + self.item_codes_nb_consumables['eye_care'] = \ + {ic('Tetracycline eye ointment, 1 %, tube 5 mg'): 5} # ------------------------------------- SEPSIS - FULL SUPPORTIVE CARE --------------------------------------- + # Whilst abx for newborns are weight based the maximum dose does not exceed the minimum unit for the costing + # model self.item_codes_nb_consumables['sepsis_supportive_care_core'] = \ - get_list_of_items(self, ['Benzylpenicillin 1g (1MU), PFR_Each_CMST', - 'Gentamicin 40mg/ml, 2ml_each_CMST', - 'Oxygen, 1000 liters, primarily with oxygen cylinders']) + {ic('Benzylpenicillin 1g (1MU), PFR_Each_CMST'): 1, + ic('Gentamicin 40mg/ml, 2ml_each_CMST'): 1, + ic('Oxygen, 1000 liters, primarily with oxygen cylinders'): 5760 # + } self.item_codes_nb_consumables['sepsis_supportive_care_optional'] = \ - get_list_of_items(self, ['Dextrose (glucose) 5%, 1000ml_each_CMST', - 'Tube, feeding CH 8_each_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Giving set iv administration + needle 15 drops/ml_each_CMST', - 'Disposables gloves, powder free, 100 pieces per box']) + {ic('Dextrose (glucose) 5%, 1000ml_each_CMST'): 500, + ic('Tube, feeding CH 8_each_CMST'): 1, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Disposables gloves, powder free, 100 pieces per box'): 1 + } # ---------------------------------------- SEPSIS - ANTIBIOTICS --------------------------------------------- - self.item_codes_nb_consumables['sepsis_abx'] =\ - get_list_of_items(self, ['Benzylpenicillin 1g (1MU), PFR_Each_CMST', - 'Gentamicin 40mg/ml, 2ml_each_CMST']) + self.item_codes_nb_consumables['sepsis_abx'] = \ + {ic('Benzylpenicillin 1g (1MU), PFR_Each_CMST'): 1, + ic('Gentamicin 40mg/ml, 2ml_each_CMST'): 1, + } def initialise_simulation(self, sim): # For the first period (2010-2015) we use the first value in each list as a parameter @@ -969,8 +979,9 @@ def assessment_and_treatment_newborn_sepsis(self, hsi_event, facility_type): # check consumables avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_nb_consumables, core='sepsis_supportive_care_core', - optional='sepsis_supportive_care_optional') + self, hsi_event, + cons=self.item_codes_nb_consumables['sepsis_supportive_care_core'], + opt_cons=self.item_codes_nb_consumables['sepsis_supportive_care_optional']) # Then, if the consumables are available, treatment for sepsis is delivered if avail and sf_check: @@ -980,8 +991,9 @@ def assessment_and_treatment_newborn_sepsis(self, hsi_event, facility_type): # The same pattern is then followed for health centre care else: avail = pregnancy_helper_functions.return_cons_avail( - self, hsi_event, self.item_codes_nb_consumables, core='sepsis_abx', - optional='iv_drug_equipment') + self, hsi_event, + cons=self.item_codes_nb_consumables['sepsis_abx'], + opt_cons=self.item_codes_nb_consumables['iv_drug_equipment']) if avail and sf_check: df.at[person_id, 'nb_inj_abx_neonatal_sepsis'] = True diff --git a/src/tlo/methods/postnatal_supervisor.py b/src/tlo/methods/postnatal_supervisor.py index 25a2d54f6d..5d99968cef 100644 --- a/src/tlo/methods/postnatal_supervisor.py +++ b/src/tlo/methods/postnatal_supervisor.py @@ -1274,21 +1274,23 @@ def apply(self, person_id, squeeze_factor): return # Define the consumables - of_repair_cons = pregnancy_helper_functions.get_list_of_items( - self, ['Scalpel blade size 22 (individually wrapped)_100_CMST', - 'Halothane (fluothane)_250ml_CMST', - 'Ceftriaxone 1g, PFR_each_CMST', - 'Metronidazole 200mg_1000_CMST', - 'Cannula iv (winged with injection pot) 18_each_CMST', - 'Paracetamol, tablet, 500 mg', - 'Declofenac injection_each_CMST', - 'Pethidine, 50 mg/ml, 2 ml ampoule', - 'Foley catheter', - 'Bag, urine, collecting, 2000 ml', - "ringer's lactate (Hartmann's solution), 1000 ml_12_IDA", - 'Sodium chloride, injectable solution, 0,9 %, 500 ml', - "Giving set iv administration + needle 15 drops/ml_each_CMST", - "Chlorhexidine 1.5% solution_5_CMST"]) + ic = self.sim.modules['HealthSystem'].get_item_code_from_item_name + + of_repair_cons = \ + {ic('Scalpel blade size 22 (individually wrapped)_100_CMST'): 1, + ic('Halothane (fluothane)_250ml_CMST'): 100, + ic('Ceftriaxone 1g, PFR_each_CMST'): 2, + ic('Metronidazole 200mg_1000_CMST'): 6000, + ic('Cannula iv (winged with injection pot) 18_each_CMST'): 1, + ic('Paracetamol, tablet, 500 mg'): 8000, + ic('Declofenac injection_each_CMST'): 1, + ic('Foley catheter'): 1, + ic('Bag, urine, collecting, 2000 ml'): 1, + ic("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, + ic('Sodium chloride, injectable solution, 0,9 %, 500 ml'): 2000, + ic('Giving set iv administration + needle 15 drops/ml_each_CMST'): 1, + ic('Chlorhexidine 1.5% solution_5_CMST'): 50, + } self.get_consumables(item_codes=of_repair_cons) diff --git a/src/tlo/methods/pregnancy_helper_functions.py b/src/tlo/methods/pregnancy_helper_functions.py index 20a712f134..8f7faa0503 100644 --- a/src/tlo/methods/pregnancy_helper_functions.py +++ b/src/tlo/methods/pregnancy_helper_functions.py @@ -21,7 +21,7 @@ def get_list_of_items(self, item_list): return codes -def return_cons_avail(self, hsi_event, cons_dict, **info): +def return_cons_avail(self, hsi_event, cons, opt_cons): """ This function is called by majority of interventions across maternal and neonatal modules to return whether a consumable or package of consumables are available. If analysis is not being conducted (as indicated by a series of @@ -38,21 +38,12 @@ def return_cons_avail(self, hsi_event, cons_dict, **info): ps_params = self.sim.modules['PregnancySupervisor'].current_parameters la_params = self.sim.modules['Labour'].current_parameters - # If 'number' is passed as an optional argument then a predetermined number of consumables will be requested - if 'number' in info.keys(): - core_cons = {cons_dict[info['core']][0]: info['number']} - else: - core_cons = cons_dict[info['core']] - - # If 'optional' is passed then the optional set of consumables is selected from the consumables dict - if 'optional' in info.keys(): - opt_cons = cons_dict[info['optional']] - else: + if opt_cons is None: opt_cons = [] # Check if analysis is currently running, if not then availability is determined normally if not ps_params['ps_analysis_in_progress'] and not la_params['la_analysis_in_progress']: - available = hsi_event.get_consumables(item_codes=core_cons, + available = hsi_event.get_consumables(item_codes=cons, optional_item_codes=opt_cons) if not available and (hsi_event.target in mni) and (hsi_event != 'AntenatalCare_Outpatient'): @@ -61,7 +52,7 @@ def return_cons_avail(self, hsi_event, cons_dict, **info): return available else: - available = hsi_event.get_consumables(item_codes=core_cons, optional_item_codes=opt_cons) + available = hsi_event.get_consumables(item_codes=cons, optional_item_codes=opt_cons) # Depending on HSI calling this function a different parameter set is used to determine if analysis is being # conducted diff --git a/src/tlo/methods/rti.py b/src/tlo/methods/rti.py index 654378c4bf..f591f5aa7b 100644 --- a/src/tlo/methods/rti.py +++ b/src/tlo/methods/rti.py @@ -3823,21 +3823,21 @@ def apply(self, person_id, squeeze_factor): # TODO: find a more complete list of required consumables for adults if is_child: self.module.item_codes_for_consumables_required['shock_treatment_child'] = { - get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1, - get_item_code("Dextrose (glucose) 5%, 1000ml_each_CMST"): 1, + get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 500, + get_item_code("Dextrose (glucose) 5%, 1000ml_each_CMST"): 500, get_item_code('Cannula iv (winged with injection pot) 18_each_CMST'): 1, - get_item_code('Blood, one unit'): 1, - get_item_code("Oxygen, 1000 liters, primarily with oxygen cylinders"): 1 + get_item_code('Blood, one unit'): 2, + get_item_code("Oxygen, 1000 liters, primarily with oxygen cylinders"): 23_040 } is_cons_available = self.get_consumables( self.module.item_codes_for_consumables_required['shock_treatment_child'] ) else: self.module.item_codes_for_consumables_required['shock_treatment_adult'] = { - get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1, + get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, get_item_code('Cannula iv (winged with injection pot) 18_each_CMST'): 1, - get_item_code('Blood, one unit'): 1, - get_item_code("Oxygen, 1000 liters, primarily with oxygen cylinders"): 1 + get_item_code('Blood, one unit'): 2, + get_item_code("Oxygen, 1000 liters, primarily with oxygen cylinders"): 23_040 } is_cons_available = self.get_consumables( self.module.item_codes_for_consumables_required['shock_treatment_adult'] @@ -3935,7 +3935,7 @@ def apply(self, person_id, squeeze_factor): # If they have a fracture that needs a cast, ask for plaster of paris self.module.item_codes_for_consumables_required['fracture_treatment'] = { get_item_code('Plaster of Paris (POP) 10cm x 7.5cm slab_12_CMST'): fracturecastcounts, - get_item_code('Bandage, crepe 7.5cm x 1.4m long , when stretched'): slingcounts, + get_item_code('Bandage, crepe 7.5cm x 1.4m long , when stretched'): 200, } is_cons_available = self.get_consumables( self.module.item_codes_for_consumables_required['fracture_treatment'] @@ -4058,9 +4058,9 @@ def apply(self, person_id, squeeze_factor): # If they have an open fracture, ask for consumables to treat fracture if open_fracture_counts > 0: self.module.item_codes_for_consumables_required['open_fracture_treatment'] = { - get_item_code('Ceftriaxone 1g, PFR_each_CMST'): 1, - get_item_code('Cetrimide 15% + chlorhexidine 1.5% solution.for dilution _5_CMST'): 1, - get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 1, + get_item_code('Ceftriaxone 1g, PFR_each_CMST'): 2000, + get_item_code('Cetrimide 15% + chlorhexidine 1.5% solution.for dilution _5_CMST'): 500, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 100, get_item_code('Suture pack'): 1, } # If wound is "grossly contaminated" administer Metronidazole @@ -4068,9 +4068,10 @@ def apply(self, person_id, squeeze_factor): p = self.module.parameters prob_open_fracture_contaminated = p['prob_open_fracture_contaminated'] rand_for_contamination = self.module.rng.random_sample(size=1) + # NB: Dose used below from BNF is for surgical prophylaxsis if rand_for_contamination < prob_open_fracture_contaminated: self.module.item_codes_for_consumables_required['open_fracture_treatment'].update( - {get_item_code('Metronidazole, injection, 500 mg in 100 ml vial'): 1} + {get_item_code('Metronidazole, injection, 500 mg in 100 ml vial'): 1500} ) # Check that there are enough consumables to treat this person's fractures is_cons_available = self.get_consumables( @@ -4169,7 +4170,7 @@ def apply(self, person_id, squeeze_factor): if lacerationcounts > 0: self.module.item_codes_for_consumables_required['laceration_treatment'] = { get_item_code('Suture pack'): lacerationcounts, - get_item_code('Cetrimide 15% + chlorhexidine 1.5% solution.for dilution _5_CMST'): lacerationcounts, + get_item_code('Cetrimide 15% + chlorhexidine 1.5% solution.for dilution _5_CMST'): 500, } # check the number of suture kits required and request them @@ -4277,7 +4278,7 @@ def apply(self, person_id, squeeze_factor): # check if they have multiple burns, which implies a higher burned total body surface area (TBSA) which # will alter the treatment plan self.module.item_codes_for_consumables_required['burn_treatment'].update( - {get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1} + {get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 4000} ) is_cons_available = self.get_consumables( @@ -4463,20 +4464,20 @@ def apply(self, person_id, squeeze_factor): description='Summary of the pain medicine requested by each person') if df.loc[person_id, 'age_years'] < 16: self.module.item_codes_for_consumables_required['pain_management'] = { - get_item_code("Paracetamol 500mg_1000_CMST"): 1 + get_item_code("Paracetamol 500mg_1000_CMST"): 8000 } cond = self.get_consumables( self.module.item_codes_for_consumables_required['pain_management'] ) else: self.module.item_codes_for_consumables_required['pain_management'] = { - get_item_code("diclofenac sodium 25 mg, enteric coated_1000_IDA"): 1 + get_item_code("diclofenac sodium 25 mg, enteric coated_1000_IDA"): 300 } cond1 = self.get_consumables( self.module.item_codes_for_consumables_required['pain_management'] ) self.module.item_codes_for_consumables_required['pain_management'] = { - get_item_code("Paracetamol 500mg_1000_CMST"): 1 + get_item_code("Paracetamol 500mg_1000_CMST"): 8000 } cond2 = self.get_consumables( self.module.item_codes_for_consumables_required['pain_management'] @@ -4533,7 +4534,7 @@ def apply(self, person_id, squeeze_factor): data=dict_to_output, description='Summary of the pain medicine requested by each person') self.module.item_codes_for_consumables_required['pain_management'] = { - get_item_code("tramadol HCl 100 mg/2 ml, for injection_100_IDA"): 1 + get_item_code("tramadol HCl 100 mg/2 ml, for injection_100_IDA"): 300 } is_cons_available = self.get_consumables( self.module.item_codes_for_consumables_required['pain_management'] @@ -4565,7 +4566,7 @@ def apply(self, person_id, squeeze_factor): description='Summary of the pain medicine requested by each person') # give morphine self.module.item_codes_for_consumables_required['pain_management'] = { - get_item_code("morphine sulphate 10 mg/ml, 1 ml, injection (nt)_10_IDA"): 1 + get_item_code("morphine sulphate 10 mg/ml, 1 ml, injection (nt)_10_IDA"): 120 } is_cons_available = self.get_consumables( self.module.item_codes_for_consumables_required['pain_management'] @@ -4725,22 +4726,22 @@ def apply(self, person_id, squeeze_factor): # Request first draft of consumables used in major surgery self.module.item_codes_for_consumables_required['major_surgery'] = { # request a general anaesthetic - get_item_code("Halothane (fluothane)_250ml_CMST"): 1, + get_item_code("Halothane (fluothane)_250ml_CMST"): 100, # clean the site of the surgery - get_item_code("Chlorhexidine 1.5% solution_5_CMST"): 1, + get_item_code("Chlorhexidine 1.5% solution_5_CMST"): 500, # tools to begin surgery get_item_code("Scalpel blade size 22 (individually wrapped)_100_CMST"): 1, # administer an IV get_item_code('Cannula iv (winged with injection pot) 18_each_CMST'): 1, get_item_code("Giving set iv administration + needle 15 drops/ml_each_CMST"): 1, - get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1, + get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, # repair incision made get_item_code("Suture pack"): 1, - get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 100, # administer pain killer - get_item_code('Pethidine, 50 mg/ml, 2 ml ampoule'): 1, + get_item_code('Pethidine, 50 mg/ml, 2 ml ampoule'): 6, # administer antibiotic - get_item_code("Ampicillin injection 500mg, PFR_each_CMST"): 1, + get_item_code("Ampicillin injection 500mg, PFR_each_CMST"): 1000, # equipment used by surgeon, gloves and facemask get_item_code('Disposables gloves, powder free, 100 pieces per box'): 1, get_item_code('surgical face mask, disp., with metal nose piece_50_IDA'): 1, @@ -5061,22 +5062,22 @@ def apply(self, person_id, squeeze_factor): # Request first draft of consumables used in major surgery self.module.item_codes_for_consumables_required['minor_surgery'] = { # request a local anaesthetic - get_item_code("Halothane (fluothane)_250ml_CMST"): 1, + get_item_code("Halothane (fluothane)_250ml_CMST"): 100, # clean the site of the surgery - get_item_code("Chlorhexidine 1.5% solution_5_CMST"): 1, + get_item_code("Chlorhexidine 1.5% solution_5_CMST"): 500, # tools to begin surgery get_item_code("Scalpel blade size 22 (individually wrapped)_100_CMST"): 1, # administer an IV get_item_code('Cannula iv (winged with injection pot) 18_each_CMST'): 1, get_item_code("Giving set iv administration + needle 15 drops/ml_each_CMST"): 1, - get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 1, + get_item_code("ringer's lactate (Hartmann's solution), 1000 ml_12_IDA"): 2000, # repair incision made get_item_code("Suture pack"): 1, - get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 1, + get_item_code("Gauze, absorbent 90cm x 40m_each_CMST"): 100, # administer pain killer - get_item_code('Pethidine, 50 mg/ml, 2 ml ampoule'): 1, + get_item_code('Pethidine, 50 mg/ml, 2 ml ampoule'): 6, # administer antibiotic - get_item_code("Ampicillin injection 500mg, PFR_each_CMST"): 1, + get_item_code("Ampicillin injection 500mg, PFR_each_CMST"): 1000, # equipment used by surgeon, gloves and facemask get_item_code('Disposables gloves, powder free, 100 pieces per box'): 1, get_item_code('surgical face mask, disp., with metal nose piece_50_IDA'): 1, diff --git a/src/tlo/methods/tb.py b/src/tlo/methods/tb.py index b769e60fb9..053469a253 100644 --- a/src/tlo/methods/tb.py +++ b/src/tlo/methods/tb.py @@ -743,6 +743,7 @@ def get_consumables_for_dx_and_tx(self): ) # 4) -------- Define the treatment options -------- + # treatment supplied as full kits for duration of treatment # adult treatment - primary self.item_codes_for_consumables_required['tb_tx_adult'] = \ hs.get_item_code_from_item_name("Cat. I & III Patient Kit A") @@ -760,12 +761,16 @@ def get_consumables_for_dx_and_tx(self): hs.get_item_code_from_item_name("Cat. II Patient Kit A2") # mdr treatment - self.item_codes_for_consumables_required['tb_mdrtx'] = { - hs.get_item_code_from_item_name("Treatment: second-line drugs"): 1} + self.item_codes_for_consumables_required['tb_mdrtx'] = \ + hs.get_item_code_from_item_name("Treatment: second-line drugs") # ipt - self.item_codes_for_consumables_required['tb_ipt'] = { - hs.get_item_code_from_item_name("Isoniazid/Pyridoxine, tablet 300 mg"): 1} + self.item_codes_for_consumables_required['tb_ipt'] = \ + hs.get_item_code_from_item_name("Isoniazid/Pyridoxine, tablet 300 mg") + + # 3hp + self.item_codes_for_consumables_required['tb_3HP'] = \ + hs.get_item_code_from_item_name("Isoniazid/Rifapentine") def initialise_population(self, population): @@ -2102,8 +2107,9 @@ def apply(self, person_id, squeeze_factor): return self.sim.modules["HealthSystem"].get_blank_appt_footprint() treatment_regimen = self.select_treatment(person_id) + # treatment supplied in kits, one kit per treatment course treatment_available = self.get_consumables( - item_codes=self.module.item_codes_for_consumables_required[treatment_regimen] + item_codes={self.module.item_codes_for_consumables_required[treatment_regimen]: 1} ) # if require MDR treatment, and not currently at level 2, refer to level 2 @@ -2340,8 +2346,9 @@ class HSI_Tb_Start_or_Continue_Ipt(HSI_Event, IndividualScopeEventMixin): * HIV.HSI_Hiv_StartOrContinueTreatment for PLHIV, diagnosed and on ART * Tb.HSI_Tb_StartTreatment for up to 5 contacts of diagnosed active TB case - if person referred by ART initiation (HIV+), IPT given for 36 months - paediatric IPT is 6-9 months + Isoniazid preventive therapy for HIV-infected children : 6 months, 180 doses + 3HP (Isoniazid/Rifapentine) for adults: 12 weeks, 12 doses + 3HP for children ages >2 yrs hiv- """ def __init__(self, module, person_id): @@ -2381,10 +2388,23 @@ def apply(self, person_id, squeeze_factor): else: # Check/log use of consumables, and give IPT if available - # if not available, reschedule IPT start - if self.get_consumables( - item_codes=self.module.item_codes_for_consumables_required["tb_ipt"] - ): + + # if child and HIV+ or child under 2 yrs + if ((person["age_years"] <= 15) and person["hv_inf"]) or (person["age_years"] <= 2): + + # 6 months dispensation, once daily + drugs_available = self.get_consumables( + item_codes={self.module.item_codes_for_consumables_required["tb_ipt"]: 180}) + + # for all others + else: + # 12 weeks dispensation, once weekly + drugs_available = self.get_consumables( + item_codes={self.module.item_codes_for_consumables_required["tb_3HP"]: 12} + ) + + # if available, schedule IPT decision + if drugs_available: # Update properties df.at[person_id, "tb_on_ipt"] = True df.at[person_id, "tb_date_ipt"] = self.sim.date diff --git a/tests/test_maternal_health_helper_and_analysis_functions.py b/tests/test_maternal_health_helper_and_analysis_functions.py index 83a93c224d..daea95a5e6 100644 --- a/tests/test_maternal_health_helper_and_analysis_functions.py +++ b/tests/test_maternal_health_helper_and_analysis_functions.py @@ -258,9 +258,9 @@ def test_analysis_events_force_availability_of_consumables_when_scheduled_in_anc syph_test = module.item_codes_preg_consumables['syphilis_test'] syph_treat = module.item_codes_preg_consumables['syphilis_treatment'] - for cons in iron, protein, calcium, syph_test, syph_treat: - sim.modules['HealthSystem'].override_availability_of_consumables( - {cons[0]: 0.0}) + for cons in 'iron_folic_acid', 'balanced_energy_protein', 'calcium', 'syphilis_test', 'syphilis_treatment': + updated_cons = {k: v * 0 for (k, v) in module.item_codes_preg_consumables[cons].items()} + sim.modules['HealthSystem'].override_availability_of_consumables(updated_cons) # refresh the consumables sim.modules['HealthSystem'].consumables._refresh_availability_of_consumables(date=sim.date)