def change_node_property(cb, target_property_name, target_property_value, start_day=0, daily_prob=1, max_duration=0, revert=0, nodeIDs=[], node_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): node_cfg = {'class': 'NodeSetAll'} if nodeIDs: node_cfg = {'class': 'NodeSetNodeList', 'Node_List': nodeIDs} node_property_value_changer = { "class": "NodePropertyValueChanger", "Target_NP_Key_Value": "%s:%s" % (target_property_name, target_property_value), "Daily_Probability": daily_prob, "Maximum_Duration": max_duration, "Revert": revert } if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ str( triggered_campaign_delay_event(cb, start_day, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration)) ] changer_event = { "class": "CampaignEvent", "Start_Day": int(start_day), "Nodeset_Config": node_cfg, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Blackout_Event_Trigger": "Node_Property_Change_Blackout", # we don't care about this, just need something to be here so the blackout works at all "Blackout_Period": 1, # so we only distribute the node event(s) once "Blackout_On_First_Occurrence": 1, "Duration": listening_duration, "Trigger_Condition_List": trigger_condition_list, "Actual_IndividualIntervention_Config": node_property_value_changer } } } if node_property_restrictions: changer_event["Event_Coordinator_Config"]["Intervention_Config"][ 'Node_Property_Restrictions'] = node_property_restrictions cb.add_event(changer_event) else: prop_ch_config = { 'class': 'StandardInterventionDistributionEventCoordinator', "Intervention_Config": node_property_value_changer } if node_property_restrictions: prop_ch_config['Intervention_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions event = { "class": "CampaignEvent", "Start_Day": start_day, "Event_Coordinator_Config": prop_ch_config, "Nodeset_Config": node_cfg } cb.add_event(event)
def add_ITN_age_season(config_builder, start=1, coverage_all=1, waning={}, discard={}, age_dep={}, seasonal_dep={}, cost=5, nodeIDs=[], as_birth=False, duration=-1, triggered_campaign_delay=0, trigger_condition_list=[], ind_property_restrictions=[], node_property_restrictions=[]): """ Add an ITN intervention to the config_builder passed. "as_birth" and "triggered_condition_list" are nutually exlusive with "as_birth" trumping the trigger You will need to add the following custom events: "Bednet_Discarded", "Bednet_Got_New_One", "Bednet_Using" :param config_builder: The :py:class:`DTKConfigBuilder <dtk.utils.core.DTKConfigBuilder>` holding the campaign that will receive the ITN event :param start: The start day of the bed net distribution :param coverage_all: Fraction of the population receiving bed nets in a given distribution event :param waning: A dictionary defining the durability and initial potency of killing and blocking. Rates assume exponential decay. :param discard: A dictionary defining the net retention rates. Default is no discarding of nets. :param age_dep: A dictionary defining the age dependence of net use. Default is uniform across all ages. :param seasonal_dep: A dictionary defining the seasonal dependence of net use. Default is constant use during the year. :param cost: Set the ``Cost_To_Consumer`` parameter :param nodeIDs: If empty, all nodes will get the intervention. If set, only the nodeIDs specified will receive the intervention. :param as_birth: If true, event is specified as a birth-triggered intervention. :param duration: If run as a birth-triggered event or a trigger_condition_list, specifies the duration for the distribution to continue. Default is to continue until the end of the simulation. :param trigger_condition_list: sets up a NodeLevelHealthTriggeredIV that listens for the defined trigger string event before giving out the intervention, "as_birth" and "trigger_condition_list" options are mutually exclusive, if "as_birth" is true, trigger_condition_list will be ignored. :param ind_property_restrictions: Restricts irs based on list of individual properties in format [{"BitingRisk":"High"}, {"IsCool":"Yes}] :param node_property_restrictions: restricts irs based on list of node properties in format [{"Place":"RURAL"}, {"ByALake":"Yes}] :return: Nothing """ # Assign net protective properties # # Unless specified otherwise, use the default values kill_initial = 0.6 block_initial = 0.9 kill_decay = 1460 block_decay = 730 if waning: if 'kill_initial' in waning.keys(): kill_initial = waning['kill_initial'] if 'block_initial' in waning.keys(): block_initial = waning['block_initial'] if 'kill_decay' in waning.keys(): kill_decay = waning['kill_decay'] if 'block_decay' in waning.keys(): block_decay = waning['block_decay'] # Assign seasonal net usage # # Times are days of the year # Input can be provided either as (times, values) for linear spline or (min coverage, day of maximum coverage) # under the assumption of sinusoidal dynamics. In the first case, the same value should be provided # for both 0 and 365; times > 365 will be ignored. if all([k in seasonal_dep.keys() for k in ['times', 'values']]): seasonal_times = seasonal_dep['times'] seasonal_values = seasonal_dep['values'] elif all([k in seasonal_dep.keys() for k in ['min_cov', 'max_day']]): seasonal_times = np.append(np.arange(0, 361, 30), 365) if seasonal_dep['min_cov'] == 0: seasonal_dep[ 'min_cov'] = seasonal_dep['min_cov'] + sys.float_info.epsilon seasonal_values = (1-seasonal_dep['min_cov'])/2*np.cos(2*np.pi/365*(seasonal_times-seasonal_dep['max_day'])) + \ (1 + seasonal_dep['min_cov'])/2 else: seasonal_times = np.append(np.arange(0, 361, 30), 365) seasonal_values = np.linspace(1, 1, len(seasonal_times)) # Assign age-dependent net usage # # Times are ages in years (note difference from seasonal dependence) if all([k in age_dep.keys() for k in ['times', 'values']]): age_times = age_dep['times'] age_values = age_dep['values'] elif all([ k in age_dep.keys() for k in ['youth_cov', 'youth_min_age', 'youth_max_age'] ]): age_times = [ 0, age_dep['youth_min_age'] - 0.1, age_dep['youth_min_age'], age_dep['youth_max_age'] - 0.1, age_dep['youth_max_age'] ] age_values = [1, 1, age_dep['youth_cov'], age_dep['youth_cov'], 1] else: age_times = [ 0, 125 ] # Dan B has hard-coded an upper limit of 125, will return error for larger values age_values = [1, 1] # Assign net ownership retention times # # Mean discard times in days; coverage half-life is discard time * ln(2) if all( [k in discard.keys() for k in ['halflife1', 'halflife2', 'fraction1'] ]): # Two retention subgroups discard_time1 = discard['halflife1'] discard_time2 = discard['halflife2'] discard_fraction1 = discard['fraction1'] elif 'halflife' in discard.keys(): # Single mean retention time discard_time1 = discard['halflife'] discard_time2 = 365 * 40 discard_fraction1 = 1 else: # No discard of nets discard_time1 = 365 * 40 discard_time2 = 365 * 40 discard_fraction1 = 1 # Assign node IDs # # Defaults to all nodes unless a node set is specified if not nodeIDs: nodeset_config = NodeSetAll() else: nodeset_config = NodeSetNodeList(Node_List=nodeIDs) itn_campaign = MultiInterventionDistributor(Intervention_List=[ UsageDependentBednet( Bednet_Type="ITN", Blocking_Config=WaningEffectExponential( Decay_Time_Constant=block_decay, Initial_Effect=block_initial), Cost_To_Consumer=cost, Killing_Config=WaningEffectExponential( Decay_Time_Constant=kill_decay, Initial_Effect=kill_initial), Usage_Config_List=[ WaningEffectMapLinearAge(Initial_Effect=1.0, Durability_Map={ "Times": list(age_times), "Values": list(age_values) }), WaningEffectMapLinearSeasonal( Initial_Effect=1.0, Durability_Map={ "Times": list(seasonal_times), "Values": list(seasonal_values) }) ], Received_Event="Bednet_Got_New_One", Using_Event="Bednet_Using", Discard_Event="Bednet_Discarded", Expiration_Distribution_Type= UsageDependentBednet_Expiration_Distribution_Type_Enum. DUAL_TIMESCALE_DURATION, Expiration_Period_1=discard_time1, Expiration_Period_2=discard_time2, Expiration_Percentage_Period_1=discard_fraction1) ]) # General or birth-triggered if as_birth: itn_event = CampaignEvent( Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=BirthTriggeredIV( Actual_IndividualIntervention_Config=itn_campaign, Demographic_Coverage=coverage_all, Duration=duration)), Nodeset_Config=nodeset_config, Start_Day=start) if ind_property_restrictions: itn_event.Event_Coordinator_Config.Intervention_Config.Property_Restrictions_Within_Node = ind_property_restrictions if node_property_restrictions: itn_event.Event_Coordinator_Config.Intervention_Config.Node_Property_Restrictions = node_property_restrictions else: if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ triggered_campaign_delay_event(config_builder, start, nodeIDs, triggered_campaign_delay, trigger_condition_list, duration) ] itn_event = CampaignEvent( Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=NodeLevelHealthTriggeredIV( Demographic_Coverage=coverage_all, Duration=duration, Target_Residents_Only=True, Trigger_Condition_List=trigger_condition_list, Property_Restrictions_Within_Node= ind_property_restrictions, Node_Property_Restrictions=node_property_restrictions, Actual_IndividualIntervention_Config=itn_campaign)), Nodeset_Config=nodeset_config, Start_Day=start) else: itn_event = CampaignEvent( Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=itn_campaign, Target_Demographic= StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum .Everyone, Demographic_Coverage=coverage_all, Property_Restrictions_Within_Node=ind_property_restrictions, Node_Property_Restrictions=node_property_restrictions, Duration=duration), Nodeset_Config=nodeset_config, Start_Day=start) config_builder.add_event(itn_event)
def add_ITN(config_builder, start, coverage_by_ages, waning={}, cost=None, nodeIDs=[], node_property_restrictions=[], ind_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=1): """ Add an ITN intervention to the config_builder passed. :param config_builder: The :py:class:`DTKConfigBuilder <dtk.utils.core.DTKConfigBuilder>` holding the campaign that will receive the ITN event :param start: The start day of the bednet distribution :param coverage_by_ages: a list of dictionaries defining the coverage per age group [{"coverage":1,"min": 1, "max": 10},{"coverage":1,"min": 11, "max": 50},{ "coverage":0.5, "birth":"birth", "duration":34}] birthtriggered(in coverage_by_age) and triggered_condition_list are mututally exclusive. "birth" option will be ingnored if you're using trigger_condition_list :param waning: a dictionary defining the durability of the nets. if empty the default decay profile will be used. For example, update usage duration to 180 days as waning={'Usage_Config' : {"Expected_Discard_Time": 180}} :param cost: Set the ``Cost_To_Consumer`` parameter :param nodeIDs: If empty, all nodes will get the intervention. If set, only the nodeIDs specified will receive the intervention. :param node_property_restrictions: restricts itn based on list of node properties in format [{"Place":"RURAL"}, {"ByALake":"Yes, "LovelyWeather":"No}] :param ind_property_restrictions: Restricts itn based on list of individual properties in format [{"BitingRisk":"High", "IsCool":"Yes}, {"IsRich": "Yes"}] :param triggered_campaign_delay: how many time steps after receiving the trigger will the campaign start. Eligibility of people or nodes for campaign is evaluated on the start day, not the triggered day. :param trigger_condition_list: when not empty, the start day is the day to start listening for the trigger conditions listed, distributing the spraying when the trigger is heard. This does not distribute the BirthTriggered intervention. :param listening_duration: how long the distributed event will listen for the trigger for, default is 1, which is indefinitely :return: Nothing """ if waning: for cfg in waning: itn_bednet[cfg].update(waning[cfg]) if cost: itn_bednet['Cost_To_Consumer'] = cost itn_bednet_w_event = { "Intervention_List": [itn_bednet, receiving_itn_event], "class": "MultiInterventionDistributor" } nodeset_config = { "class": "NodeSetAll" } if not nodeIDs else { "class": "NodeSetNodeList", "Node_List": nodeIDs } for coverage_by_age in coverage_by_ages: if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ triggered_campaign_delay_event(config_builder, start, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration) ] if not 'birth' in coverage_by_age.keys(): ITN_event = { "class": "CampaignEvent", "Start_Day": int(start), "Nodeset_Config": nodeset_config, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Trigger_Condition_List": trigger_condition_list, "Duration": listening_duration, "Demographic_Coverage": coverage_by_age["coverage"], "Target_Residents_Only": 1, "Property_Restrictions_Within_Node": ind_property_restrictions, 'Node_Property_Restrictions': node_property_restrictions, "Actual_IndividualIntervention_Config": itn_bednet_w_event } } } if all([k in coverage_by_age.keys() for k in ['min', 'max']]): ITN_event["Event_Coordinator_Config"][ "Intervention_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": coverage_by_age["min"], "Target_Age_Max": coverage_by_age["max"] }) else: ITN_event = { "class": "CampaignEvent", "Start_Day": int(start), "Nodeset_Config": nodeset_config, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Target_Residents_Only": 1, "Demographic_Coverage": coverage_by_age["coverage"], "Intervention_Config": itn_bednet_w_event } } if all([k in coverage_by_age.keys() for k in ['min', 'max']]): ITN_event["Event_Coordinator_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": coverage_by_age["min"], "Target_Age_Max": coverage_by_age["max"] }) if 'birth' in coverage_by_age.keys() and coverage_by_age['birth']: birth_triggered_intervention = { "class": "BirthTriggeredIV", "Duration": coverage_by_age.get( 'duration', 1), # default to forever if duration not specified "Demographic_Coverage": coverage_by_age["coverage"], "Actual_IndividualIntervention_Config": itn_bednet_w_event #itn_bednet } ITN_event["Event_Coordinator_Config"][ "Intervention_Config"] = birth_triggered_intervention ITN_event["Event_Coordinator_Config"].pop( "Demographic_Coverage") ITN_event["Event_Coordinator_Config"].pop( "Target_Residents_Only") if ind_property_restrictions and 'birth' in coverage_by_age.keys( ) and coverage_by_age['birth']: ITN_event["Event_Coordinator_Config"]["Intervention_Config"][ "Property_Restrictions_Within_Node"] = ind_property_restrictions elif ind_property_restrictions: ITN_event["Event_Coordinator_Config"][ "Property_Restrictions_Within_Node"] = ind_property_restrictions if node_property_restrictions: ITN_event['Event_Coordinator_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions config_builder.add_event(ITN_event)
def change_individual_property(cb, target_property_name, target_property_value, target='Everyone', start_day=0, coverage=1, daily_prob=1, max_duration=0, revert=0, nodeIDs=[], node_property_restrictions=[], ind_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): node_cfg = {'class': 'NodeSetAll'} if nodeIDs: node_cfg = {'class': 'NodeSetNodeList', 'Node_List': nodeIDs} property_value_changer = { "class": "PropertyValueChanger", "Target_Property_Key": target_property_name, "Target_Property_Value": target_property_value, "Daily_Probability": daily_prob, "Maximum_Duration": max_duration, "Revert": revert } if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ str( triggered_campaign_delay_event(cb, start_day, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration)) ] changer_event = { "class": "CampaignEvent", "Start_Day": start_day, "Nodeset_Config": node_cfg, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Blackout_Event_Trigger": "Ind_Property_Blackout", # we don't care about this, just need something to be here so the blackout works at all "Blackout_Period": 1, # so we only distribute the node event(s) once "Blackout_On_First_Occurrence": 1, "Target_Residents_Only": 1, "Duration": listening_duration, "Trigger_Condition_List": trigger_condition_list, "Target_Residents_Only": 1, "Demographic_Coverage": coverage, "Actual_IndividualIntervention_Config": property_value_changer } } } if isinstance(target, dict) and all( [k in target for k in ['agemin', 'agemax']]): changer_event["Event_Coordinator_Config"][ "Intervention_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": target['agemin'], "Target_Age_Max": target['agemax'] }) else: changer_event["Event_Coordinator_Config"][ "Intervention_Config"].update({"Target_Demographic": target}) # default is Everyone if node_property_restrictions: changer_event["Event_Coordinator_Config"]["Intervention_Config"][ 'Node_Property_Restrictions'] = node_property_restrictions if ind_property_restrictions: changer_event['Event_Coordinator_Config']['Intervention_Config'][ "Property_Restrictions_Within_Node"] = ind_property_restrictions cb.add_event(changer_event) else: prop_ch_config = { 'class': 'StandardInterventionDistributionEventCoordinator', "Demographic_Coverage": coverage, "Intervention_Config": property_value_changer } if isinstance(target, dict) and all( [k in target for k in ['agemin', 'agemax']]): prop_ch_config.update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": target['agemin'], "Target_Age_Max": target['agemax'] }) else: prop_ch_config.update({"Target_Demographic": target}) # default is Everyone if node_property_restrictions: prop_ch_config['Intervention_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions if ind_property_restrictions: prop_ch_config['Intervention_Config'][ "Property_Restrictions_Within_Node"] = ind_property_restrictions event = { "class": "CampaignEvent", "Start_Day": start_day, "Event_Coordinator_Config": prop_ch_config, "Nodeset_Config": node_cfg } cb.add_event(event)
def add_ivermectin(config_builder, drug_code, coverage, start_days, trigger_condition_list=[], triggered_campaign_delay=0, listening_duration=-1, nodeids=[], target_residents_only=1, node_property_restrictions=[], ind_property_restrictions=[]): """ Add an ivermectin event to the config_builder passed. :param config_builder: The config builder getting the intervention event :param drug_code: Can be 'DAY', 'WEEK' or 'MONTH' and drive the ``Killing_config`` (see `Killing_Config in Ivermectin <https://institutefordiseasemodeling.github.io/EMOD/malaria/parameter-campaign.html#iv-ivermectin>`_ for more info). :param coverage: Set the ``Demographic_Coverage`` :param start_days: list of days when to start the ivermectin distribution :param trigger_condition_list: ivermectin will be distributed when it hears the trigger string event, please note the start_days then is used to distribute the NodeLevelHealthTriggeredIV :param listening_duration: for how long the NLHTIV will listen for the trigger :return: Nothing """ cfg = ivermectin_config_by_duration(drug_code) cfg = [cfg] + [receiving_IV_event] intervention_cfg = MultiInterventionDistributor(Intervention_List=cfg) if triggered_campaign_delay > 0: trigger_condition_list = [ triggered_campaign_delay_event( config_builder, start_days[0], nodeIDs=nodeids, triggered_campaign_delay=triggered_campaign_delay, trigger_condition_list=trigger_condition_list, listening_duration=listening_duration, node_property_restrictions=node_property_restrictions) ] if nodeids: node_cfg = NodeSetNodeList(Node_List=nodeids) else: node_cfg = NodeSetAll() for start_day in start_days: IVM_event = CampaignEvent( Start_Day=start_day, Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator(), Nodeset_Config=node_cfg) if trigger_condition_list: IVM_event.Event_Coordinator_Config.Intervention_Config = NodeLevelHealthTriggeredIV( Trigger_Condition_List=trigger_condition_list, Target_Residents_Only=target_residents_only, Property_Restrictions_Within_Node=ind_property_restrictions, Node_Property_Restrictions=node_property_restrictions, Duration=listening_duration, Demographic_Coverage=coverage, Actual_IndividualIntervention_Config=intervention_cfg) else: IVM_event.Event_Coordinator_Config.Target_Residents_Only = True if target_residents_only else False IVM_event.Event_Coordinator_Config.Demographic_Coverage = coverage IVM_event.Event_Coordinator_Config.Property_Restrictions_Within_Node = ind_property_restrictions IVM_event.Event_Coordinator_Config.Node_Property_Restrictions = node_property_restrictions IVM_event.Event_Coordinator_Config.Intervention_Config = intervention_cfg config_builder.add_event(IVM_event)
def add_diagnostic_survey(cb, coverage=1, repetitions=1, tsteps_btwn=365, target='Everyone', start_day=0, diagnostic_type='TRUE_PARASITE_DENSITY', diagnostic_threshold=40, event_name="Diagnostic Survey", node_cfg={"class": "NodeSetAll"}, positive_diagnosis_configs=[], received_test_event='Received_Test', IP_restrictions=[], NP_restrictions=[], pos_diag_IP_restrictions=[], trigger_condition_list=[], listening_duration=-1, triggered_campaign_delay=0 ): """ Function to add recurring prevalence surveys with configurable diagnostic When using "trigger_condition_list", the diagnostic is triggered by the words listed :param cb: Configuration builder holding the interventions :param repetitions: Number of repetitions :param tsteps_btwn: Timesteps between repetitions :param target: Target demographic. Default is 'Everyone' :param start_day: Start day for the outbreak :param coverage: probability an individual receives the diagnostic :param diagnostic_type: BLOOD_SMEAR PCR PF_HRP2 TRUE_PARASITE_DENSITY HAS_FEVER :param diagnostic_threshold : Detection_Threshold becomes a parameter required by all types. The units of the threshold depend on the diagnostic type selected. BLOOD_SMEAR Use the SusceptibilityMalaria::CheckParasiteCountWithTest() (or at least logic) to get a parasite density to check against the threshold PCR Use the ReportUtilitiesMalaria::NASBADensityWithUncertainty() method to calculate a measured parasite density and check against the threshold PF_HRP2 Add a new method to get the PfHRP2 value and check against the threshold TRUE_PARASITE_DENSITY Check the true/actual parasite density against the threshold HAS_FEVER Check the person's fever against the threshold :param nodes: nodes to target. # All nodes: {"class": "NodeSetAll"}. # Subset of nodes: {"class": "NodeSetNodeList", "Node_List": list_of_nodeIDs} :param positive_diagnosis_configs: list of events to happen to individual who receive a positive result from test :param received_test_event: string for individuals to broadcast upon receiving diagnostic :param IP_restrictions: list of IndividualProperty restrictions to restrict who takes action upon positive diagnosis :param NP_restrictions: node property restrictions :param trigger_condition_list: list of strings that will trigger a diagnostic survey. :param listening_duration: for diagnostics that are listening for trigger_condition_list, how long after start day to stop listening for the event :param triggered_campaign_delay: delay of running the campaign/intervention after receiving a trigger from the trigger_condition_list :return: nothing """ # OLD version of DTK, without PfHRP2-enabled MalariaDiagnostic: # diagnostic_type options: Microscopy, NewDetectionTech, Other # intervention_cfg = { # "Diagnostic_Type": diagnostic_type, # "Detection_Threshold": diagnostic_threshold, # "class": "MalariaDiagnostic" # } intervention_cfg = { "MalariaDiagnostic_Type": diagnostic_type, "Detection_Threshold": diagnostic_threshold, "class": "MalariaDiagnostic" } if not positive_diagnosis_configs : intervention_cfg["Event_Or_Config"] = "Event" intervention_cfg["Positive_Diagnosis_Event"] = "TestedPositive" else : intervention_cfg["Event_Or_Config"] = "Config" intervention_cfg["Positive_Diagnosis_Config"] = { "Intervention_List" : positive_diagnosis_configs + [positive_broadcast] , "class" : "MultiInterventionDistributor" } if pos_diag_IP_restrictions : intervention_cfg["Positive_Diagnosis_Config"]["Property_Restrictions_Within_Node"] = pos_diag_IP_restrictions if trigger_condition_list: if repetitions > 1 or triggered_campaign_delay > 0: # create a trigger for each of the delays. trigger_condition_list = [triggered_campaign_delay_event(cb, start_day, nodeIDs=node_cfg, triggered_campaign_delay=triggered_campaign_delay + x * tsteps_btwn, trigger_condition_list=trigger_condition_list, listening_duration=listening_duration, node_property_restrictions=NP_restrictions) for x in range(repetitions)] survey_event = {"class": "CampaignEvent", "Start_Day": start_day, "Event_Name": event_name, "Nodeset_Config": node_cfg, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Number_Distributions": -1, "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Trigger_Condition_List": trigger_condition_list, "Target_Residents_Only": 1, "Duration": listening_duration, "Demographic_Coverage": coverage, "Target_Demographic": target, "Property_Restrictions_Within_Node": IP_restrictions, "Node_Property_Restrictions": NP_restrictions, "Actual_IndividualIntervention_Config": { "class": "MultiInterventionDistributor", "Intervention_List": [ { "class": "BroadcastEvent", "Broadcast_Event": received_test_event }, intervention_cfg ] } }, } } if isinstance(target, dict) and all([k in target.keys() for k in ['agemin', 'agemax']]): survey_event["Event_Coordinator_Config"]['Intervention_Config'].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": target['agemin'], "Target_Age_Max": target['agemax']}) cb.add_event(RawCampaignObject(survey_event)) else: survey_event = { "class" : "CampaignEvent", "Start_Day": start_day, "Event_Name" : event_name, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Node_Property_Restrictions": NP_restrictions, "Property_Restrictions_Within_Node": IP_restrictions, "Number_Distributions": -1, "Number_Repetitions": repetitions, "Timesteps_Between_Repetitions": tsteps_btwn, "Demographic_Coverage": coverage, "Intervention_Config": { "Intervention_List" : [ { "class": "BroadcastEvent", "Broadcast_Event": received_test_event }, intervention_cfg ] , "class" : "MultiInterventionDistributor" } }, "Nodeset_Config": node_cfg } if isinstance(target, dict) and all([k in target.keys() for k in ['agemin','agemax']]) : survey_event["Event_Coordinator_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": target['agemin'], "Target_Age_Max": target['agemax'] }) else : survey_event["Event_Coordinator_Config"].update({ "Target_Demographic": target } ) # default is Everyone cb.add_event(RawCampaignObject(survey_event)) return
def add_ITN(config_builder, start, coverage_by_ages, waning={}, cost=0, nodeIDs=[], node_property_restrictions=[], ind_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): """ Add an ITN intervention to the config_builder passed. birth-triggered(in coverage_by_age) and triggered_condition_list are mututally exclusive. "birth" option will be ingnored if you're using trigger_condition_list :param config_builder: The :py:class:`DTKConfigBuilder <dtk.utils.core.DTKConfigBuilder>` holding the campaign that will receive the ITN event :param start: The start day of the bednet distribution :param coverage_by_ages: a list of dictionaries defining the coverage per age group [{"coverage":1,"min": 1, "max": 10},{"coverage":1,"min": 11, "max": 50},{ "coverage":0.5, "birth":"birth", "duration":34}] :param waning: a dictionary defining the durability of the nets. if empty the default decay profile will be used. For example, update usage duration to 180 days as waning={'Usage_Config' : {"Expected_Discard_Time": 180}} :param cost: Set the ``Cost_To_Consumer`` parameter :param nodeIDs: If empty, all nodes will get the intervention. If set, only the nodeIDs specified will receive the intervention. :param node_property_restrictions: restricts itn based on list of node properties in format [{"Place":"RURAL"}, {"ByALake":"Yes, "LovelyWeather":"No}] :param ind_property_restrictions: Restricts itn based on list of individual properties in format [{"BitingRisk":"High", "IsCool":"Yes}, {"IsRich": "Yes"}] :param triggered_campaign_delay: how many time steps after receiving the trigger will the campaign start. Eligibility of people or nodes for campaign is evaluated on the start day, not the triggered day. :param trigger_condition_list: when not empty, the start day is the day to start listening for the trigger conditions listed, distributing the spraying when the trigger is heard. This does not distribute the BirthTriggered intervention. :param listening_duration: how long the distributed event will listen for the trigger for, default is -1, which is indefinitely :return: Nothing """ receiving_itn_event = BroadcastEvent(Broadcast_Event='Received_ITN') itn_bednet = SimpleBednet( Bednet_Type='ITN', Killing_Config=WaningEffectExponential(Initial_Effect=0.6, Decay_Time_Constant=1460), Blocking_Config=WaningEffectExponential(Initial_Effect=0.9, Decay_Time_Constant=730), Usage_Config=WaningEffectRandomBox(Expected_Discard_Time=3650, Initial_Effect=1.0), Cost_To_Consumer=3.75) # [TODO] # if waning: # for cfg in waning : # itn_bednet[cfg].update(waning[cfg]) itn_bednet.Cost_To_Consumer = cost itn_bednet_w_event = MultiInterventionDistributor( Intervention_List=[itn_bednet, receiving_itn_event]) # Assign node IDs # # Defaults to all nodes unless a node set is specified if not nodeIDs: nodeset_config = NodeSetAll() else: nodeset_config = NodeSetNodeList(Node_List=nodeIDs) if triggered_campaign_delay: trigger_condition_list = [ str( triggered_campaign_delay_event(config_builder, start, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration)) ] for coverage_by_age in coverage_by_ages: if trigger_condition_list: if not 'birth' in coverage_by_age.keys(): intervention_config = NodeLevelHealthTriggeredIV( Trigger_Condition_List=trigger_condition_list, Duration=listening_duration, Demographic_Coverage=coverage_by_age["coverage"], Target_Residents_Only=1, Actual_IndividualIntervention_Config= itn_bednet_w_event # itn_bednet ) ITN_event = CampaignEvent( Start_Day=int(start), Nodeset_Config=nodeset_config, Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=intervention_config)) if all([k in coverage_by_age.keys() for k in ['min', 'max']]): ITN_event_e_i = ITN_event.Event_Coordinator_Config.Intervention_Config ITN_event_e_i.Target_Demographic = "ExplicitAgeRanges" ITN_event_e_i.Target_Age_Min = coverage_by_age["min"] ITN_event_e_i.Target_Age_Max = coverage_by_age["max"] if ind_property_restrictions: ITN_event_e_i.Property_Restrictions_Within_Node = ind_property_restrictions if node_property_restrictions: ITN_event_e_i.Node_Property_Restrictions = node_property_restrictions else: event_coordinator_config = StandardInterventionDistributionEventCoordinator( Node_Property_Restrictions=[], Target_Residents_Only=1, Demographic_Coverage=coverage_by_age["coverage"], Intervention_Config=itn_bednet_w_event # itn_bednet ) ITN_event = CampaignEvent( Start_Day=int(start), Nodeset_Config=nodeset_config, Event_Coordinator_Config=event_coordinator_config) if node_property_restrictions: ITN_event.Event_Coordinator_Config.Node_Property_Restrictions.extend( node_property_restrictions) if all([k in coverage_by_age.keys() for k in ['min', 'max']]): ITN_event.Event_Coordinator_Config.Target_Demographic = "ExplicitAgeRanges" ITN_event.Event_Coordinator_Config.Target_Age_Min = coverage_by_age[ "min"] ITN_event.Event_Coordinator_Config.Target_Age_Max = coverage_by_age[ "max"] if 'birth' in coverage_by_age.keys() and coverage_by_age['birth']: birth_triggered_intervention = BirthTriggeredIV( Duration=coverage_by_age.get( 'duration', -1), # default to forever if duration not specified Demographic_Coverage=coverage_by_age["coverage"], Actual_IndividualIntervention_Config= itn_bednet_w_event # itn_bednet ) ITN_event.Event_Coordinator_Config.Intervention_Config = birth_triggered_intervention ITN_event.Event_Coordinator_Config.pop( "Demographic_Coverage") # [TODO]: delete member? ITN_event.Event_Coordinator_Config.pop( "Target_Residents_Only") # [TODO]: delete member? if ind_property_restrictions: ITN_event.Event_Coordinator_Config.Intervention_Config.Property_Restrictions_Within_Node = ind_property_restrictions elif ind_property_restrictions: ITN_event.Event_Coordinator_Config.Property_Restrictions_Within_Node = ind_property_restrictions config_builder.add_event(ITN_event.to_json()) # TEST return ITN_event
def add_MDA(cb, start_days, coverage, drug_configs, receiving_drugs_event, repetitions, interval, nodes, expire_recent_drugs, node_property_restrictions, ind_property_restrictions, target_group, trigger_condition_list=[], listening_duration=-1, triggered_campaign_delay=0, target_residents_only=1): interventions = drug_configs + [receiving_drugs_event] if expire_recent_drugs: interventions = interventions + [expire_recent_drugs] drugstatus = {"DrugStatus": "None"} if ind_property_restrictions: for item in ind_property_restrictions: item.update(drugstatus) else: ind_property_restrictions = [drugstatus] if trigger_condition_list: if repetitions > 1 or triggered_campaign_delay > 0: trigger_condition_list = [ triggered_campaign_delay_event( cb, start_days[0], nodeIDs=nodes, triggered_campaign_delay=triggered_campaign_delay + x * interval, trigger_condition_list=trigger_condition_list, listening_duration=listening_duration, node_property_restrictions=node_property_restrictions) for x in range(repetitions) ] drug_event = { "class": "CampaignEvent", "Start_Day": start_days[0], "Nodeset_Config": nodes, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Target_Demographic": "Everyone", "Node_Property_Restrictions": node_property_restrictions, "Property_Restrictions_Within_Node": ind_property_restrictions, "Demographic_Coverage": coverage, "Trigger_Condition_List": trigger_condition_list, "Duration": listening_duration, "Target_Residents_Only": target_residents_only, "Actual_IndividualIntervention_Config": { "class": "MultiInterventionDistributor", "Intervention_List": interventions } } } } if target_group != 'Everyone': drug_event['Event_Coordinator_Config'][ 'Intervention_Config'].update({ "Target_Demographic": "ExplicitAgeRanges", # Otherwise default is Everyone "Target_Age_Min": target_group['agemin'], "Target_Age_Max": target_group['agemax'] }) cb.add_event(drug_event) else: for start_day in start_days: drug_event = { "class": "CampaignEvent", "Start_Day": start_day, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Target_Demographic": "Everyone", "Node_Property_Restrictions": node_property_restrictions, "Property_Restrictions_Within_Node": ind_property_restrictions, "Demographic_Coverage": coverage, "Intervention_Config": { "class": "MultiInterventionDistributor", "Intervention_List": interventions }, "Number_Repetitions": repetitions, "Timesteps_Between_Repetitions": interval }, "Nodeset_Config": nodes } if target_group != 'Everyone': drug_event['Event_Coordinator_Config'].update({ "Target_Demographic": "ExplicitAgeRanges", # Otherwise default is Everyone "Target_Age_Min": target_group['agemin'], "Target_Age_Max": target_group['agemax'] }) cb.add_event(drug_event)
def add_migration_event(cb, nodeto, start_day=0, coverage=1, repetitions=1, tsteps_btwn=365, duration_at_node_distr_type='FIXED_DURATION', duration_of_stay=100, duration_of_stay_2=0, duration_before_leaving_distr_type='FIXED_DURATION', duration_before_leaving=0, duration_before_leaving_2=0, target='Everyone', nodesfrom={"class": "NodeSetAll"}, ind_property_restrictions=[], node_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): migration_event = MigrateIndividuals( NodeID_To_Migrate_To=nodeto, Is_Moving=False ) migration_event = update_duration_type(migration_event, duration_at_node_distr_type, dur_param_1=duration_of_stay, dur_param_2=duration_of_stay_2, leaving_or_at='at') migration_event = update_duration_type(migration_event, duration_before_leaving_distr_type, dur_param_1=duration_before_leaving, dur_param_2=duration_before_leaving_2, leaving_or_at='leaving') if trigger_condition_list: if repetitions > 1 or triggered_campaign_delay > 0: event_to_send_out = random.randrange(100000) for x in range(repetitions): # create a trigger for each of the delays. triggered_campaign_delay_event(cb, start_day, nodesfrom, triggered_campaign_delay + x * tsteps_btwn, trigger_condition_list, listening_duration, event_to_send_out) trigger_condition_list = [str(event_to_send_out)] event = CampaignEvent( Event_Name="Migration Event Triggered", Start_Day=start_day, Event_Coordinator_Config=StandardInterventionDistributionEventCoordinator( Intervention_Config=NodeLevelHealthTriggeredIV( Duration=listening_duration, Trigger_Condition_List=trigger_condition_list, Target_Demographic=StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum[target], Target_Residents_Only=True, Node_Property_Restrictions=node_property_restrictions, Property_Restrictions_Within_Node=ind_property_restrictions, Demographic_Coverage=coverage, Actual_IndividualIntervention_Config=migration_event ) ), Nodeset_Config=nodesfrom ) if isinstance(target, dict) and all([k in target.keys() for k in ['agemin', 'agemax']]): event.Event_Coordinator_Config.Intervention_Config.Target_Demographic = StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum.ExplicitAgeRanges event.Event_Coordinator_Config.Intervention_Config.Target_Age_Min = target['agemin'] event.Event_Coordinator_Config.Intervention_Config.Target_Age_Max = target['agemax'] else: event = CampaignEvent( Event_Name="Migration Event", Start_Day=start_day, Event_Coordinator_Config=StandardInterventionDistributionEventCoordinator( Property_Restrictions_Within_Node=ind_property_restrictions, Node_Property_Restrictions=node_property_restrictions, Number_Distributions=-1, Number_Repetitions=repetitions, Target_Residents_Only=True, Target_Demographic=StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum[target], Timesteps_Between_Repetitions=tsteps_btwn, Demographic_Coverage=coverage, Intervention_Config=migration_event ), Nodeset_Config=nodesfrom ) if isinstance(target, dict) and all([k in target for k in ['agemin', 'agemax']]): event.Event_Coordinator_Config.Target_Demographic = StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum.ExplicitAgeRanges event.Event_Coordinator_Config.Target_Age_Min = target['agemin'] event.Event_Coordinator_Config.Target_Age_Max = target['agemax'] cb.add_event(event)
def change_node_property(cb, target_property_name, target_property_value, start_day=0, daily_prob=1, max_duration=0, revert=0, nodeIDs=[], node_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): node_cfg = NodeSetAll() if nodeIDs: node_cfg = NodeSetNodeList(Node_List=nodeIDs) node_property_value_changer = NodePropertyValueChanger( Target_NP_Key_Value="%s:%s" % (target_property_name, target_property_value), Daily_Probability=daily_prob, Maximum_Duration=max_duration, Revert=revert) if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ str( triggered_campaign_delay_event(cb, start_day, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration)) ] changer_event = CampaignEvent( Start_Day=int(start_day), Nodeset_Config=node_cfg, Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=NodeLevelHealthTriggeredIV( Blackout_Event_Trigger= "Node_Property_Change_Blackout", # [TODO]: enum?? # we don't care about this, just need something to be here so the blackout works at all Blackout_Period= 1, # so we only distribute the node event(s) once Blackout_On_First_Occurrence=1, Duration=listening_duration, Trigger_Condition_List=trigger_condition_list, Actual_IndividualIntervention_Config= node_property_value_changer))) if node_property_restrictions: changer_event.Event_Coordinator_Config.Intervention_Config.Node_Property_Restrictions = node_property_restrictions cb.add_event(changer_event) else: prop_ch_config = StandardInterventionDistributionEventCoordinator( Intervention_Config=node_property_value_changer) if node_property_restrictions: prop_ch_config.Intervention_Config.Node_Property_Restrictions = node_property_restrictions event = CampaignEvent(Start_Day=start_day, Event_Coordinator_Config=prop_ch_config, Nodeset_Config=node_cfg) cb.add_event(event)
def change_individual_property(cb, target_property_name, target_property_value, target='Everyone', start_day=0, coverage=1, daily_prob=1, max_duration=0, revert=0, nodeIDs=[], node_property_restrictions=[], ind_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): node_cfg = NodeSetAll() if nodeIDs: node_cfg = NodeSetNodeList(Node_List=nodeIDs) property_value_changer = PropertyValueChanger( Target_Property_Key=target_property_name, Target_Property_Value=target_property_value, Daily_Probability=daily_prob, Maximum_Duration=max_duration, Revert=revert) if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ triggered_campaign_delay_event( cb, start_day, nodeIDs=nodeIDs, triggered_campaign_delay=triggered_campaign_delay, trigger_condition_list=trigger_condition_list, listening_duration=listening_duration) ] changer_event = CampaignEvent( Start_Day=start_day, Nodeset_Config=node_cfg, Event_Coordinator_Config= StandardInterventionDistributionEventCoordinator( Intervention_Config=NodeLevelHealthTriggeredIV( Blackout_Event_Trigger="Ind_Property_Blackout", # we don't care about this, just need something to be here so the blackout works at all Blackout_Period=1, # so we only distribute the node event(s) once Blackout_On_First_Occurrence=True, Target_Residents_Only=False, Duration=listening_duration, Trigger_Condition_List=trigger_condition_list, # Target_Residents_Only=1, # [ZDU]: duplicated Demographic_Coverage=coverage, Actual_IndividualIntervention_Config=property_value_changer ))) if isinstance(target, dict) and all( [k in target for k in ['agemin', 'agemax']]): changer_event.Event_Coordinator_Config.Intervention_Config.Target_Demographic = StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum.ExplicitAgeRanges changer_event.Event_Coordinator_Config.Intervention_Config.Target_Age_Min = target[ 'agemin'] changer_event.Event_Coordinator_Config.Intervention_Config.Target_Age_Max = target[ 'agemax'] else: changer_event.Event_Coordinator_Config.Intervention_Config.Target_Demographic = NodeLevelHealthTriggeredIV_Target_Demographic_Enum[ target] # default is Everyone if node_property_restrictions: changer_event.Event_Coordinator_Config.Intervention_Config.Node_Property_Restrictions = node_property_restrictions if ind_property_restrictions: changer_event.Event_Coordinator_Config.Intervention_Config.Property_Restrictions_Within_Node = ind_property_restrictions cb.add_event(changer_event) else: prop_ch_config = StandardInterventionDistributionEventCoordinator( Demographic_Coverage=coverage, Intervention_Config=property_value_changer) if isinstance(target, dict) and all( [k in target for k in ['agemin', 'agemax']]): prop_ch_config.Target_Demographic = StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum.ExplicitAgeRanges prop_ch_config.Target_Age_Min = target['agemin'] prop_ch_config.Target_Age_Max = target['agemax'] else: prop_ch_config.Target_Demographic = StandardInterventionDistributionEventCoordinator_Target_Demographic_Enum[ target] # default is Everyone if node_property_restrictions: prop_ch_config.Intervention_Config.Node_Property_Restrictions = node_property_restrictions if ind_property_restrictions: prop_ch_config.Intervention_Config.Property_Restrictions_Within_Node = ind_property_restrictions event = CampaignEvent(Start_Day=start_day, Event_Coordinator_Config=prop_ch_config, Nodeset_Config=node_cfg) cb.add_event(event)
def add_IRS(config_builder, start, coverage_by_ages, cost=None, nodeIDs=[], initial_killing=0.5, duration=90, waning={}, node_property_restrictions=[], ind_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): """ Add an IRS intervention to the config_builder passed. Please note that using trigger_condition_list does not work for birth-triggered ("birth" in coverage_by_ages). when using trigger_condition_list, the "birth" option will be ignored. :param config_builder: The :py:class:`DTKConfigBuilder <dtk.utils.core.DTKConfigBuilder>` holding the campaign that will receive the IRS event :param start: The start day of the spraying :param coverage_by_ages: a list of dictionaries defining the coverage per age group or birth-triggered intervention [{"coverage":1,"min": 1, "max": 10},{"coverage":1,"min": 11, "max": 50},{ "coverage":0.5, "birth":"birth", "duration":34}] :param cost: Set the ``Cost_To_Consumer`` parameter :param nodeIDs: If empty, all nodes will get the intervention. If set, only the nodeIDs specified will receive the intervention. :param initial_killing: sets Initial Effect within the killing config :param duration: sets the Decal_Time_Constant within the killing config :param waning: a dictionary defining the durability of the nets. if empty the default ``DECAYDURABILITY`` with 1 year primary and 1 year secondary will be used. :param ind_property_restrictions: Restricts irs based on list of individual properties in format [{"BitingRisk":"High"}, {"IsCool":"Yes}] :param node_property_restrictions: restricts irs based on list of node properties in format [{"Place":"RURAL"}, {"ByALake":"Yes}] :param triggered_campaign_delay: how many time steps after receiving the trigger will the campaign start. Eligibility of people or nodes for campaign is evaluated on the start day, not the triggered day. :param trigger_condition_list: when not empty, the start day is the day to start listening for the trigger conditions listed, distributing the spraying when the trigger is heard. This does not distribute the BirthTriggered intervention. :param listening_duration: how long the distributed event will listen for the trigger for, default is -1, which is indefinitely :return: Nothing """ receiving_irs_event = { "class": "BroadcastEvent", "Broadcast_Event": "Received_IRS" } irs_housingmod['Killing_Config']['Initial_Effect'] = initial_killing irs_housingmod['Killing_Config']['Decay_Time_Constant'] = duration if waning: for cfg in waning: irs_housingmod[cfg].update(waning[cfg]) if cost: irs_housingmod['Cost_To_Consumer'] = cost irs_housingmod_w_event = { "Intervention_List": [irs_housingmod, receiving_irs_event], "class": "MultiInterventionDistributor" } nodeset_config = { "class": "NodeSetAll" } if not nodeIDs else { "class": "NodeSetNodeList", "Node_List": nodeIDs } if triggered_campaign_delay: trigger_condition_list = [ triggered_campaign_delay_event(config_builder, start, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration) ] for coverage_by_age in coverage_by_ages: if trigger_condition_list: if 'birth' not in coverage_by_age.keys(): IRS_event = { "class": "CampaignEvent", "Start_Day": int(start), "Nodeset_Config": nodeset_config, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Intervention_Config": { "class": "NodeLevelHealthTriggeredIV", "Trigger_Condition_List": trigger_condition_list, "Duration": listening_duration, "Property_Restrictions_Within_Node": ind_property_restrictions, "Node_Property_Restrictions": node_property_restrictions, "Demographic_Coverage": coverage_by_age["coverage"], "Target_Residents_Only": 1, "Actual_IndividualIntervention_Config": irs_housingmod_w_event } } } if all([k in coverage_by_age.keys() for k in ['min', 'max']]): IRS_event["Event_Coordinator_Config"][ "Intervention_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": coverage_by_age["min"], "Target_Age_Max": coverage_by_age["max"] }) config_builder.add_event(IRS_event) else: IRS_event = { "class": "CampaignEvent", "Start_Day": int(start), "Nodeset_Config": nodeset_config, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", "Demographic_Coverage": coverage_by_age["coverage"], "Target_Residents_Only": 1, "Intervention_Config": irs_housingmod_w_event } } if all([k in coverage_by_age.keys() for k in ['min', 'max']]): IRS_event["Event_Coordinator_Config"].update({ "Target_Demographic": "ExplicitAgeRanges", "Target_Age_Min": coverage_by_age["min"], "Target_Age_Max": coverage_by_age["max"] }) if 'birth' in coverage_by_age.keys() and coverage_by_age['birth']: birth_triggered_intervention = { "class": "BirthTriggeredIV", "Duration": coverage_by_age.get( 'duration', -1), # default to forever if duration not specified "Demographic_Coverage": coverage_by_age["coverage"], "Actual_IndividualIntervention_Config": irs_housingmod_w_event } IRS_event["Event_Coordinator_Config"][ "Intervention_Config"] = birth_triggered_intervention IRS_event["Event_Coordinator_Config"].pop( "Demographic_Coverage") IRS_event["Event_Coordinator_Config"].pop( "Target_Residents_Only") if ind_property_restrictions and 'birth' in coverage_by_age.keys( ) and coverage_by_age['birth']: IRS_event["Event_Coordinator_Config"]["Intervention_Config"][ "Property_Restrictions_Within_Node"] = ind_property_restrictions elif ind_property_restrictions: IRS_event["Event_Coordinator_Config"][ "Property_Restrictions_Within_Node"] = ind_property_restrictions if node_property_restrictions: IRS_event['Event_Coordinator_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions config_builder.add_event(IRS_event)
def add_node_IRS(config_builder, start, initial_killing=0.5, box_duration=90, waning_effect_type='WaningEffectExponential', cost=None, irs_ineligibility_duration=0, nodeIDs=[], node_property_restrictions=[], triggered_campaign_delay=0, trigger_condition_list=[], listening_duration=-1): irs_config = copy.deepcopy(node_irs_config) irs_config['Killing_Config']['class'] = waning_effect_type irs_config['Killing_Config']['Initial_Effect'] = initial_killing irs_config['Killing_Config']['Decay_Time_Constant'] = box_duration if waning_effect_type == 'WaningEffectBox': irs_config['Killing_Config']['Box_Duration'] = box_duration del irs_config['Killing_Config']['Decay_Time_Constant'] if not nodeIDs: nodeset_config = {"class": "NodeSetAll"} else: nodeset_config = {"class": "NodeSetNodeList", "Node_List": nodeIDs} if cost: node_irs_config['Cost_To_Consumer'] = cost node_sprayed_event = { "class": "BroadcastEvent", "Broadcast_Event": "Node_Sprayed" } IRS_event = { "class": "CampaignEvent", "Start_Day": int(start), "Nodeset_Config": nodeset_config, "Event_Coordinator_Config": { "class": "StandardInterventionDistributionEventCoordinator", 'Node_Property_Restrictions': node_property_restrictions, "Intervention_Config": { "Intervention_List": [irs_config, node_sprayed_event], "class": "MultiInterventionDistributor" } }, "Event_Name": "Node Level IRS" } if trigger_condition_list: if triggered_campaign_delay: trigger_condition_list = [ str( triggered_campaign_delay_event(config_builder, start, nodeIDs, triggered_campaign_delay, trigger_condition_list, listening_duration)) ] IRS_event['Event_Coordinator_Config']['Intervention_Config'] = { "class": "NodeLevelHealthTriggeredIV", "Blackout_On_First_Occurrence": 1, "Blackout_Event_Trigger": "IRS_Blackout_%d" % random.randint(0, 10000), "Blackout_Period": 1, 'Node_Property_Restrictions': node_property_restrictions, "Duration": listening_duration, "Trigger_Condition_List": trigger_condition_list, "Actual_IndividualIntervention_Config": { "Intervention_List": [irs_config, node_sprayed_event], "class": "MultiInterventionDistributor" }, "Target_Residents_Only": 1 } del IRS_event['Event_Coordinator_Config']['Node_Property_Restrictions'] IRS_cfg = copy.copy(IRS_event) if irs_ineligibility_duration > 0: recent_irs = { "class": "NodePropertyValueChanger", "Target_NP_Key_Value": "SprayStatus:RecentSpray", "Daily_Probability": 1.0, "Maximum_Duration": 0, 'Revert': irs_ineligibility_duration } if trigger_condition_list: IRS_cfg['Event_Coordinator_Config']['Intervention_Config'][ 'Actual_IndividualIntervention_Config'][ "Intervention_List"].append(recent_irs) if not node_property_restrictions: IRS_cfg['Event_Coordinator_Config']['Intervention_Config'][ 'Node_Property_Restrictions'] = [{ 'SprayStatus': 'None' }] else: for n, np in enumerate(node_property_restrictions): node_property_restrictions[n]['SprayStatus'] = 'None' IRS_cfg['Event_Coordinator_Config']['Intervention_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions else: IRS_cfg['Event_Coordinator_Config']['Intervention_Config'][ 'Intervention_List'].append(recent_irs) if not node_property_restrictions: IRS_cfg['Event_Coordinator_Config'][ 'Node_Property_Restrictions'] = [{ 'SprayStatus': 'None' }] else: for n, np in enumerate(node_property_restrictions): node_property_restrictions[n]['SprayStatus'] = 'None' IRS_cfg['Event_Coordinator_Config'][ 'Node_Property_Restrictions'] = node_property_restrictions config_builder.add_event(IRS_cfg)