From 62406233c6439f5159540746364bc43de3415769 Mon Sep 17 00:00:00 2001 From: Jonathan Bloedow Date: Tue, 3 Oct 2023 14:58:59 -0700 Subject: [PATCH] Working snapshot using SimpleVaccine for main vax. --- .../interventions/typhoid_vaccine.py | 64 ++++++++++ examples/vaccination/example.py | 113 +++++++++++++----- 2 files changed, 150 insertions(+), 27 deletions(-) diff --git a/emodpy_typhoid/interventions/typhoid_vaccine.py b/emodpy_typhoid/interventions/typhoid_vaccine.py index 8c2414a..9ddcc6d 100644 --- a/emodpy_typhoid/interventions/typhoid_vaccine.py +++ b/emodpy_typhoid/interventions/typhoid_vaccine.py @@ -27,6 +27,29 @@ def new_intervention( camp, efficacy=0.82, mode="Shedding", constant_period=0, d intervention.Changing_Effect.Decay_Time_Constant = decay_constant return intervention +def new_vax( camp, efficacy=0.82, mode="Acquisition", constant_period=0, decay_constant=6935.0 ): + """ + Create a new 'SimpleVaccine' intervention with specified parameters. If you use this function directly, you'll need to distribute the intervention with a function like ScheduledCampaignEvent or TriggeredCampaignEvent from emod_api.interventions.common. + + Args: + camp (Camp): The camp to which the intervention is applied. + efficacy (float, optional): The efficacy of the Typhoid vaccine. Default is 0.82. + mode (str, optional): The mode of the intervention. Default is "Acquisition". + constant_period (float, optional): The constant period of the waning effect in days. Default is 0. + decay_constant (float, optional): The decay time constant for the waning effect. Default is 6935.0. + + Returns: + SimpleVaccine: A fully configured instance of the SimpleVaccine intervention with the specified parameters. + """ + + intervention = s2c.get_class_with_defaults( "SimpleVaccine", camp.schema_path ) + #intervention.Mode = mode + intervention.Waning_Config = s2c.get_class_with_defaults( "WaningEffectBoxExponential" ) + intervention.Waning_Config.Initial_Effect = efficacy + intervention.Waning_Config.Box_Duration = constant_period + intervention.Waning_Config.Decay_Time_Constant = decay_constant + return intervention + def new_triggered_intervention( camp, efficacy=0.82, @@ -65,6 +88,47 @@ def new_triggered_intervention( return event +def new_routine_immunization( + camp, + efficacy=0.82, + mode="Acquisition", + constant_period=0, + decay_constant=6935.0, + start_day=1, + child_age=9*30, + coverage=1.0, + node_ids=None, + property_restrictions_list=[], + co_event=None # expansion slot + ): + """ + Create a new birth-triggered SimpleVaccine intervention based on specified parameters. + + Args: + camp (Camp): The camp to which the intervention is applied. + efficacy (float, optional): The efficacy of the Typhoid vaccine. Default is 0.82. + mode (str, optional): The mode of the intervention. Default is "Acquisition". + constant_period (float, optional): The constant period of the waning effect in days. Default is 0. + decay_constant (float, optional): The decay time constant for the waning effect. Default is 6935.0. + start_day (int, optional): The day on which the intervention starts. Default is 1. + coverage (float, optional): Demographic coverage of the intervention. Default is 1.0. + node_ids (list, optional): List of node IDs where the intervention is applied. Default is None. + property_restrictions_list (list, optional): List of property restrictions for the intervention. Default is an empty list. + co_event (None, optional): Expansion slot for future use. + + Returns: + TriggeredCampaignEvent: An instance of a triggered campaign event with the TyphoidVaccine intervention. + """ + iv = new_vax( camp, efficacy=efficacy, mode=mode, constant_period=constant_period, decay_constant=decay_constant ) + delay = { + "Delay_Period_Min": child_age-7, + "Delay_Period_Max": child_age+7 + } + + event = common.TriggeredCampaignEvent( camp, Start_Day=start_day, Triggers=["Births"], Demographic_Coverage=coverage, Intervention_List=[ iv ], Node_Ids=node_ids, Property_Restrictions=property_restrictions_list, Event_Name="9-Month 'Typhoid' Vax", Delay=delay ) + + return event + def new_scheduled_intervention( camp, efficacy=0.82, diff --git a/examples/vaccination/example.py b/examples/vaccination/example.py index 4d987e4..6bc8de2 100755 --- a/examples/vaccination/example.py +++ b/examples/vaccination/example.py @@ -16,12 +16,16 @@ # emodpy from emodpy.emod_task import EMODTask import emodpy.emod_task -emodpy.emod_task.dev_mode = True +#emodpy.emod_task.dev_mode = True import emod_api.interventions.common as comm #comm.old_adhoc_trigger_style = False import manifest +BASE_YEAR=2010 +SIMULATION_DURATION_IN_YEARS=12 +CAMP_START_YEAR=2019 + def update_sim_bic(simulation, value): simulation.task.config.parameters.Base_Infectivity_Constant = value*0.1 return {"Base_Infectivity": value} @@ -30,20 +34,48 @@ def update_sim_random_seed(simulation, value): simulation.task.config.parameters.Run_Number = value return {"Run_Number": value} +def year_to_days( year ): + return ( (year-BASE_YEAR)*365 ) + def set_param_fn( config ): config.parameters.Simulation_Type = "TYPHOID_SIM" - config.parameters.Simulation_Duration = 50*365.0 + config.parameters.Simulation_Duration = SIMULATION_DURATION_IN_YEARS*365.0 config.parameters.Base_Individual_Sample_Rate = 0.2 #config.parameters.Enable_Birth = 0 # temporary #config.parameters.Minimum_End_Time = 90 # cover up for default bugs in schema - config.parameters.Base_Year = 2000 + config.parameters.Base_Year = BASE_YEAR config.parameters.Inset_Chart_Reporting_Start_Year = 1900 config.parameters.Inset_Chart_Reporting_Stop_Year = 2050 config.parameters.Enable_Demographics_Reporting = 0 #config.parameters.Report_Event_Recorder_Events = [ "VaccineDistributed" ] #config.parameters["Custom_Events"] = [ "VaccineDistributed" ] + #config.parameters.Typhoid_Immunity_Memory = 36500 + #config.parameters.Config_Name = "149_Typhoid" + + config.parameters.Report_Typhoid_ByAgeAndGender_Start_Year = 2010 + config.parameters.Report_Typhoid_ByAgeAndGender_Stop_Year = 2020 + config.parameters.Typhoid_3year_Susceptible_Fraction = 0 + config.parameters.Typhoid_6month_Susceptible_Fraction = 0 + config.parameters.Typhoid_6year_Susceptible_Fraction = 0 + config.parameters.Typhoid_Acute_Infectiousness = 13435 + config.parameters.Typhoid_Carrier_Probability = 0.108 + config.parameters.Typhoid_Carrier_Removal_Year = 2500 + config.parameters.Typhoid_Chronic_Relative_Infectiousness = 0.241 + config.parameters.Typhoid_Contact_Exposure_Rate = 0.06918859049226553 + config.parameters.Typhoid_Environmental_Exposure_Rate = 0.06169346985005757 + config.parameters.Typhoid_Environmental_Cutoff_Days = 157.20690133538764 + config.parameters.Typhoid_Environmental_Peak_Start = 355.0579483941714 + config.parameters.Typhoid_Environmental_Ramp_Down_Duration = 112.30224910440123 + config.parameters.Typhoid_Environmental_Ramp_Up_Duration = 39.540475369174146 + config.parameters.Typhoid_Exposure_Lambda = 7.0 + config.parameters.Typhoid_Prepatent_Relative_Infectiousness = 0.5 + config.parameters.Typhoid_Protection_Per_Infection = 0.98 + config.parameters.Typhoid_Subclinical_Relative_Infectiousness = 1 + config.parameters.Typhoid_Symptomatic_Fraction = 0.07 + + #config.parameters.x_Birth = 1.2 # when using 2018 binary import emodpy_typhoid.config as config_utils @@ -51,7 +83,7 @@ def set_param_fn( config ): return config -def build_camp( start_day=1, vax_eff = 0.82 ): +def build_camp( start_day_offset=1, vax_eff = 0.82 ): """ Build a campaign input file for the DTK using emod_api. """ @@ -61,27 +93,35 @@ def build_camp( start_day=1, vax_eff = 0.82 ): print(f"Telling emod-api to use {manifest.schema_file} as schema.") camp.set_schema( manifest.schema_file ) - event = ob.new_intervention( camp, timestep=1, cases=1 ) - camp.add( event ) + for x in range( 10 ): + event = ob.new_intervention( camp, timestep=1+x, cases=1 ) + camp.add( event ) import emodpy_typhoid.interventions.typhoid_vaccine as tv import emod_api.interventions.common as comm - #event = tv.new_triggered_intervention(camp, start_day=1, triggers=['Births'], coverage=1.0, node_ids=None, property_restrictions_list=[], co_event=None) - #camp.add( event ) - #event = tv.new_scheduled_intervention(camp, start_day=10*365, coverage=1.0, node_ids=None, property_restrictions_list=[], co_event=None) - #camp.add( event ) - tv_iv = tv.new_intervention( camp, efficacy=vax_eff ) + ria = tv.new_routine_immunization( camp, + efficacy=vax_eff, + start_day=year_to_days( CAMP_START_YEAR )+start_day_offset + ) + + """ notification_iv = comm.BroadcastEvent( camp, "VaccineDistributed" ) - #"Delay_Distribution": "FIXED_DURATION", vax_plus_msg = comm.MultiInterventionDistributor( camp, [ tv_iv, notification_iv ] ) - delay_dict = { - "Delay_Period_Min": 265, - "Delay_Period_Max": 275 - } + """ #event = comm.triggered_campaign_event_with_optional_delay( camp, start_day=1, intervention=[tv_iv,notification_iv], triggers=["Births"], delay=delay_dict ) - event = comm.triggered_campaign_event_with_optional_delay( camp, start_day=start_day, intervention=tv_iv, triggers=["Births"], delay=delay_dict ) - #event = comm.triggered_campaign_event_with_optional_delay( camp, start_day=1, intervention=vax_plus_msg, triggers=["Births"], delay=delay_dict ) - camp.add( event ) + camp.add( ria ) + + tv_iv = tv.new_vax( camp, + efficacy=vax_eff + ) + one_time_campaign = comm.ScheduledCampaignEvent( camp, + Start_Day=year_to_days( CAMP_START_YEAR )+start_day_offset, + Intervention_List=[tv_iv], + Demographic_Coverage=0.72, + Target_Age_Min=0.75, + Target_Age_Max=15 + ) + camp.add( one_time_campaign ) return camp @@ -92,8 +132,19 @@ def build_demog(): import emodpy_typhoid.demographics.TyphoidDemographics as Demographics # OK to call into emod-api demog = Demographics.from_template_node( lat=0, lon=0, pop=10000, name=1, forced_id=1 ) - wb_births_df = pd.read_csv( manifest.world_bank_dataset ) - demog.SetEquilibriumVitalDynamicsFromWorldBank( wb_births_df=wb_births_df, country='Chile', year=2005 ) + #wb_births_df = pd.read_csv( manifest.world_bank_dataset ) + #demog.SetEquilibriumVitalDynamicsFromWorldBank( wb_births_df=wb_births_df, country='Chile', year=BASE_YEAR ) + """ + demog.AddAgeDependentTransmission( + Age_Bin_Edges_In_Years = [0, 5, 20, 60, -1], + TransmissionMatrix = [ + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0], + [1.0, 1.0, 1.0, 1.0] + ] + ) + """ return demog @@ -103,9 +154,14 @@ def run_test(): platform = Platform("SLURM", node_group="idm_48cores", priority="Highest") task = EMODTask.from_default2(config_path="config.json", eradication_path=manifest.eradication_path, campaign_builder=build_camp, demog_builder=build_demog, schema_path=manifest.schema_file, param_custom_cb=set_param_fn, ep4_custom_cb=None) + #task.config.parameters.Demographics_Filenames = [ "demographics.json", "TestDemographics_pak_updated.json" ] + task.config.parameters.Demographics_Filenames = [ "TestDemographics_pak_updated.json" ] + task.config.parameters.Death_Rate_Dependence = "NONDISEASE_MORTALITY_BY_YEAR_AND_AGE_FOR_EACH_GENDER" + task.config.parameters.Birth_Rate_Dependence = "INDIVIDUAL_PREGNANCIES_BY_AGE_AND_YEAR" #print("Adding asset dir...") #task.common_assets.add_directory(assets_directory=manifest.reporters, relative_path="reporter_plugins") + task.common_assets.add_directory(assets_directory=manifest.assets_input_dir) task.set_sif( manifest.sif ) @@ -121,13 +177,14 @@ def update_campaign_start(simulation, value): simulation.task.create_campaign_from_callback(build_campaign_partial) return {"campaign_start_day": value} - #vax_effs = np.linspace(0,1.0,3) # 0.0, 0.5, 1.0 - #builder.add_sweep_definition( update_campaign_efficacy, vax_effs ) - start_days = np.linspace(1,3651,11) # 1, 366, etc. - builder.add_sweep_definition( update_campaign_start, start_days ) + vax_effs = np.linspace(0,1.0,3) # 0.0, 0.5, 1.0 + builder.add_sweep_definition( update_campaign_efficacy, vax_effs ) + builder.add_sweep_definition( update_sim_random_seed, range(5) ) + #start_day_offsets = np.linspace(0,60,7) # 1, 366, etc. + #builder.add_sweep_definition( update_campaign_start, start_day_offsets ) # create experiment from builder - experiment = Experiment.from_builder(builder, task, name="Typhoid Hello World") + experiment = Experiment.from_builder(builder, task, name="Typhoid Vax 101") # The last step is to call run() on the ExperimentManager to run the simulations. experiment.run(wait_until_done=True, platform=platform) @@ -136,8 +193,10 @@ def update_campaign_start(simulation, value): # download and plot some stuff. EMODTask.get_file_from_comps( experiment.uid, [ "InsetChart.json" ] ) task.cache_experiment_metadata_in_sql( experiment.uid ) + import matplotlib + matplotlib.use( "TkAgg" ) import emod_api.channelreports.plot_icj_means as plotter - chan_data = plotter.collect( str( experiment.uid ), "Infected" ) + chan_data = plotter.collect( str( experiment.uid ), "Infected", tag="vax_efficacy=SWEEP" ) plotter.display( chan_data, False, "Infected", str( experiment.uid ) )