diff --git a/emodpy/campaign/common.py b/emodpy/campaign/common.py index 7b0a45b..f572373 100644 --- a/emodpy/campaign/common.py +++ b/emodpy/campaign/common.py @@ -15,7 +15,7 @@ class CommonInterventionParameters: Args: cost (float, optional): - The unit 'cost' per intervention distributed. For interventions distributed to people, the cost will be - added for each person. For internventions distributed to nodes, the cost is for each node. Setting + added for each person. For interventions distributed to nodes, the cost is for each node. Setting cost to zero for all other interventions, and to a non-zero amount for one intervention, provides a convenient way to track the number of times the intervention has been applied in a simulation. - Minimum value: 0. @@ -25,9 +25,9 @@ class CommonInterventionParameters: disqualifying_properties (list[str], optional): - A list of IndividualProperty 'key:value' pairs that will prevent an intervention from being distributed or applied/updated (persistent interventions will abort/expire in the time step they see the change in - their individual property). See :ref:demo-properties parameters for more information. Generally used to - control the flow of health care access. For example, to prevent the same individual from accessing health - care via two different routes at the same time. + their individual property). See [Individual and Node Properties](https://emod.idmod.org/EMOD-Generic/md_parameter/parameter-demographics/#nodeproperties-and-individualproperties) + for more information. Generally used to control the flow of health care access. For example, to prevent + the same individual from accessing health care via two different routes at the same time. - Defaults to None. dont_allow_duplicates (bool, optional): @@ -43,10 +43,10 @@ class CommonInterventionParameters: new_property_value (str, optional): - An optional IndividualProperty 'key:value' pair that will be assigned when the intervention is first - applied/updated. See :ref:demo-properties parameters for more information. Generally used to indicate the - broad category of health care cascade to which an intervention belongs to prevent individuals from - accessing care through multiple pathways. For example, if an individual must already be taking a - particular medication to be prescribed a new one. + applied/updated. See [Individual and Node Properties](https://emod.idmod.org/EMOD-Generic/md_parameter/parameter-demographics/#nodeproperties-and-individualproperties) + for more information. Generally used to indicate the broad category of health care cascade to which + an intervention belongs to prevent individuals from accessing care through multiple pathways. For example, + if an individual must already be taking a particular medication to be prescribed a new one. - Defaults to None. """ @@ -121,8 +121,8 @@ class TargetGender(Enum): class TargetDemographicsConfig: """ A class that is used to configure the Demographics_Coverage, Target_Demographic, Target_Age_Min, Target_Age_Max, - Target_Gender and Target_Residents_Only in the coordinator class. Please refer to emodpy.campaign.distributor - for its usage. + Target_Gender and Target_Residents_Only in the coordinator class. Please refer to [emodpy.campaign.distributor](https://emod.idmod.org/emodpy/autoapi/emodpy/campaign/distributor/) + for more information about its usage. Args: demographic_coverage (float, optional): @@ -144,16 +144,18 @@ class TargetDemographicsConfig: target_residents_only (bool, optional): - When set to true, the intervention is only distributed to individuals that began the simulation in the node (i.e. those that claim the node as their residence). - - You can use the MigrateIndividuals function to modify an individual's HOME node. For more details on MigrateIndividuals, refer to the Emod documentation: [MigrateIndividuals](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-individual-migrateindividuals/) + - You can use the MigrateIndividuals function to modify an individual's HOME node. For more details on MigrateIndividuals, refer to the [EMOD documentation](https://emod.idmod.org/EMOD-Generic/md_parameter/parameter-campaign-individual-migrateindividuals/) - Defaults to False. Examples: - # replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + Replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + ``` from emodpy.campaign.common import TargetDemographicsConfig, TargetGender from emodpy.campaign.distributor import add_intervention_scheduled demographics_config = TargetDemographicsConfig(demographic_coverage=0.5, target_age_min=10, target_age_max=20, target_gender=TargetGender.FEMALE) add_intervention_scheduled(demographics_config=demographics_config, ...) + ``` """ class _TargetDemographic(Enum): EVERYONE = "Everyone" @@ -241,12 +243,13 @@ class RepetitionConfig: ValueError: if timesteps_between_repetitions is undefined when number_repetitions is used. Examples: - # replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + ``` from emodpy.campaign.common import RepetitionConfig from emodpy.campaign.distributor import add_intervention_scheduled repetition_config = RepetitionConfig(number_repetitions=2, timesteps_between_repetitions=365) add_intervention_scheduled(repetition_config=repetition_config, ...) - + ``` """ def __init__(self, number_repetitions: int = 1, timesteps_between_repetitions: int = None, infinite_repetitions: bool = False): @@ -295,7 +298,6 @@ def _set_repetitions(self, campaign_object: s2c.ReadOnlyDict): Returns: This function does not return any value; instead, it modifies the campaign_object. - """ if self.number_repetitions: campaign_object.Number_Repetitions = self.number_repetitions @@ -308,7 +310,7 @@ class PropertyRestrictions: A class that is used to configure the individual property restrictions and node property restrictions in the campaign object. - Please refer to the Emod documentation for NodeProperties and IndividualProperties parameters for more + Please refer to the EMOD documentation for NodeProperties and IndividualProperties parameters for more information: - HIV Emod: [Demographics parameters](https://emod.idmod.org/emodpy-hiv/emod/parameter-demographics/) @@ -337,30 +339,35 @@ class PropertyRestrictions: ValueError: if the elements in the inner list are not strings that represent dictionaries key:value pairs with at least one alphanumeric character before and after ':'. Examples: - Example 1: This example demonstrates how to specify individual restrictions for targeting specific groups of people who are high risk AND whose InterventionStatus is ARTStaging. - - # replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + Example 1: This example demonstrates how to specify individual restrictions for targeting specific groups + of people who are high risk AND whose InterventionStatus is ARTStaging. + ``` + replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. from emodpy.campaign.common import PropertyRestrictions from emodpy.campaign.distributor import add_intervention_scheduled property_restrictions = PropertyRestrictions(individual_property_restrictions=[["Risk:HIGH", "InterventionStatus:ARTStaging"]]) add_intervention_scheduled(property_restrictions=property_restrictions, ...) - # the result json should look like this: - # { - # "Property_Restrictions_Within_Node": [ - # { - # "Risk": "HIGH", - # "InterventionStatus": "ARTStaging" - # } - # ] - # } - - - Example 2: This example demonstrates how to specify individual restrictions for targeting specific groups of people. In this case, we are targeting individuals whose InterventionStatus is set to ARTStaging and who have either HIGH or MEDIUM risk behavior. In other words, we aim to target individuals who meet either of the following conditions: - - 1. "InterventionStatus is set to ARTStaging and Risk is set to HIGH" - 2. "InterventionStatus is set to ARTStaging AND Risk is set to MEDIUM" - - # replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + ``` + the resulting json should look like this: + ``` + { + "Property_Restrictions_Within_Node": [ + { + "Risk": "HIGH", + "InterventionStatus": "ARTStaging" + } + ] + } + ``` + Example 2: This example demonstrates how to specify individual restrictions for targeting specific groups + of people. In this case, we are targeting individuals whose InterventionStatus is set to ARTStaging and who + have either HIGH or MEDIUM risk behavior. In other words, we aim to target individuals who meet either of + the following conditions: + + 1. InterventionStatus is set to ARTStaging and Risk is set to HIGH + 2. InterventionStatus is set to ARTStaging AND Risk is set to MEDIUM + ``` + replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. from emodpy.campaign.common import PropertyRestrictions from emodpy.campaign.distributor import add_intervention_scheduled property_restrictions_within_node = PropertyRestrictions( @@ -368,26 +375,28 @@ class PropertyRestrictions: ["Risk:HIGH", "InterventionStatus:ARTStaging"], ["Risk:MEDIUM", "InterventionStatus:ARTStaging"]]) add_intervention_scheduled(property_restrictions=property_restrictions, ...) - # the result json should look like this: - # { - # "Property_Restrictions_Within_Node": [ - # { - # "Risk": "HIGH", - # "InterventionStatus": "ARTStaging" - # }, - # { - # "Risk": "MEDIUM", - # "InterventionStatus": "ARTStaging" - # } - # ] - # } - + ``` + the resulting json should look like this: + ``` + { + "Property_Restrictions_Within_Node": [ + { + "Risk": "HIGH", + "InterventionStatus": "ARTStaging" + }, + { + "Risk": "MEDIUM", + "InterventionStatus": "ARTStaging" + } + ] + } + ``` Example 3: This example demonstrates how to use 'node_property_restrictions' to specify the NodeProperty. In this case, we are targeting nodes that meet either of the following conditions: - 1. "Risk is set to MEDIUM and Place is set to URBAN" - 2. "Risk is set to LOW and Place is set to RURAL" - - # replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. + 1. Risk is set to MEDIUM and Place is set to URBAN + 2. Risk is set to LOW and Place is set to RURAL + ``` + replace emodpy with emodpy_hiv or emodpy_malaria based on the disease you are working on. from emodpy.campaign.common import PropertyRestrictions from emodpy.campaign.distributor import add_intervention_scheduled property_restrictions = PropertyRestrictions( @@ -395,20 +404,22 @@ class PropertyRestrictions: ["Risk:MEDIUM", "Place:URBAN"], ["Risk:LOW", "Place:RURAL"]]) add_intervention_scheduled(property_restrictions=property_restrictions, ...) - # the result json should look like this: - # { - # "Node_Property_Restrictions": [ - # { - # "Risk": "MEDIUM", - # "Place": "URBAN" - # }, - # { - # "Risk": "LOW", - # "Place": "RURAL" - # } - # ] - # } - + ``` + the resulting json should look like this: + ``` + { + "Node_Property_Restrictions": [ + { + "Risk": "MEDIUM", + "Place": "URBAN" + }, + { + "Risk": "LOW", + "Place": "RURAL" + } + ] + } + ``` """ def __init__(self, individual_property_restrictions: List[List[str]] = None, node_property_restrictions: List[List[str]] = None): @@ -443,23 +454,23 @@ def _set_property_restrictions(self, campaign_object: s2c.ReadOnlyDict): A function that configure the Property_Restrictions_Within_Node and Node_Property_Restrictions for the campaign_object. This function is a private function that is used by the coordinator class and should not be called directly by user code. + Args: campaign_object: An EventCoordinator or Intervention object. Returns: This function does not return any value; instead, it modifies the campaign_object. - """ def parse_to_dict(list_of_lists): """ A helper function that parse the list of lists to a list of dictionaries of key-value-pairs where each dict can only contain a given key once. + Args: list_of_lists: Returns: list of dictionaries of key-value-pairs where each dict can only contain a given key once. - """ result = [] for inner_list in list_of_lists: @@ -508,7 +519,6 @@ class ValueMap: values (List[float]): - A list of values that correspond to the times. - The list of values should have the same length as times. - """ def __init__(self, times: List[float], values: List[float]): if not isinstance(times, list) or not isinstance(values, list): diff --git a/emodpy/campaign/distributor.py b/emodpy/campaign/distributor.py index 2147109..a255b7e 100644 --- a/emodpy/campaign/distributor.py +++ b/emodpy/campaign/distributor.py @@ -84,10 +84,8 @@ def add_intervention_scheduled(campaign: api_campaign, - Please refer to the emodpy.utils.targeting_config module for more information. - If None (default), then there is not extra targeting. - Returns: - None, add the configuration to the campaign. - Examples: + ``` from emodpy.campaign.distributor import add_intervention_scheduled from emodpy.campaign.common import TargetDemographicsConfig, RepetitionConfig, PropertyRestrictions, TargetGender from emodpy.campaign.individual_intervention import BroadcastEvent, OutbreakIndividual @@ -121,6 +119,7 @@ def add_intervention_scheduled(campaign: api_campaign, # Add a uniform delay (from 0 to 365 days) before the actual intervention is distributed delay_distribution=uniform_distribution ) + ``` """ # Create a DelayedIntervention with the intervention if a delay_distribution is provided intervention_list = _add_delay(campaign, delay_distribution, intervention_list) @@ -216,6 +215,7 @@ def add_intervention_triggered(campaign: api_campaign, - If None (default), then there is not extra targeting. Examples: + ``` from emodpy.campaign.distributor import add_intervention_triggered from emodpy.campaign.common import TargetDemographicsConfig, RepetitionConfig, PropertyRestrictions, TargetGender from emodpy.campaign.individual_intervention import BroadcastEvent, OutbreakIndividual @@ -253,9 +253,7 @@ def add_intervention_triggered(campaign: api_campaign, property_restrictions=PropertyRestrictions(individual_property_restrictions=[["Risk:High"]]) targeting_config=is_not_pregnant ) - - Returns: - None, add the configuration to the campaign. + ``` """ # Create a DelayedIntervention with the intervention if a delay_distribution is provided intervention_list = _add_delay(campaign, delay_distribution, intervention_list) diff --git a/emodpy/campaign/individual_intervention.py b/emodpy/campaign/individual_intervention.py index 9a8fdb3..0f99f95 100644 --- a/emodpy/campaign/individual_intervention.py +++ b/emodpy/campaign/individual_intervention.py @@ -32,7 +32,9 @@ class BroadcastEvent(IndividualIntervention): The CommonInterventionParameters object that contains the 4 common parameters: disqualifying_properties, new_property_value, intervention_name, dont_allow_duplicates. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -55,7 +57,7 @@ class BroadcastEventToOtherNodes(IndividualIntervention): surrounding nodes. When this intervention is updated, the event to be broadcast is cached to be distributed to the nodes. - After the people have migrated, the event information is distributed to the nodes - **NOTE: it does support + After the people have migrated, the event information is distributed to the nodes. **NOTE: it does support multi-core**. During the next time step, the nodes will update their node-level interventions and then broadcast the events from other nodes to ALL the people in the node. This is different from interventions that only broadcast the event in the current node for the person who had the intervention. Distances between @@ -75,11 +77,13 @@ class BroadcastEventToOtherNodes(IndividualIntervention): node_selection_type('NodeSelectionType', optional): The method by which to select nodes to receive the event. Possible values are: + * DISTANCE_ONLY - Nodes located within the distance specified by **Max_Distance_To_Other_Nodes_Km** are selected. * MIGRATION_NODES_ONLY - Nodes that are local, regional, or connected in the migration file are selected. * DISTANCE_AND_MIGRATION - Nodes are selected using DISTANCE_ONLY and MIGRATION_NODES_ONLY criteria. + Default value: DISTANCE_ONLY max_distance_to_other_nodes_km(float, optional): @@ -98,7 +102,9 @@ class BroadcastEventToOtherNodes(IndividualIntervention): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -149,11 +155,13 @@ class ControlledVaccine(IndividualIntervention): vaccine_type(VaccineType, optional): The type of vaccine to distribute in a vaccine intervention. Possible values are: + * Generic - The vaccine can reduce transmission, acquisition, and mortality. * TransmissionBlocking - The vaccine will reduce pathogen transmission. * AcquisitionBlocking - The vaccine will reduce the acquisition of the pathogen by reducing the force of infection experienced by the vaccinated individual. * MortalityBlocking - The vaccine reduces the disease-mortality rate of a vaccinated individual. + Default value: Generic vaccine_take(float, optional): @@ -234,6 +242,7 @@ class DelayedIntervention(IndividualIntervention): The distribution type to use for assigning the delay period for distributing interventions. Each assigned value is a random draw from the distribution. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -253,7 +262,9 @@ class DelayedIntervention(IndividualIntervention): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -303,26 +314,28 @@ class IVCalendar(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - intervention_list(list[IndividualIntervention], required): + intervention_list (list[IndividualIntervention], required): An array of interventions that will be distributed as specified by the calendar. Each time the calendar says it is time for the intervention, this list of interventions will be distributed to the person with this intervention. - dropout(bool, optional): + dropout (bool, optional): If set to true, when an intervention distribution is missed, all subsequent interventions are also missed. If set to false, all calendar dates/doses are applied independently of each other. Default value: True - calendar(list['AgeAndProbability'], optional): + calendar (list['AgeAndProbability'], optional): An array of JSON objects where each object specifies the age and probability of receiving the - interventions. The parameters of the Calendar objects are Age and Probability. + interventions. The parameters of the Calendar objects are Age and Probability. Default value: None common_intervention_parameters (CommonInterventionParameters, optional): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, disqualifying_properties, dont_allow_duplicates. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -352,19 +365,19 @@ def _set_cost(self, cost: float) -> None: class AgeAndProbability: """ This class defines a single entry into the calendar of when an individual is to get a - collection of interventions. When **IVCalendar** is distributed to the individual, the + collection of interventions. When **IVCalendar** is distributed to the individual, the 'probability' is used to determine if the person will get the interventions as this age. If the person gets **IVCalendar** after 'age', they will not get the interventions. Args: - age_days(float,optional): + age_days (float,optional): As a parameter of a Calendar object, this parameter determines the age (in days) that the individual must be in order to receive the list of actual interventions. Minimum value: 0 Maximum value: 125 * 365 = 45,625 Default value: 0 - probability(float,optional): + probability (float,optional): As a parameter of a Calendar object, this parameter determines the probability of an individual receiving the list of actual interventions at the corresponding age. Minimum value: 0 @@ -401,27 +414,27 @@ class _ImmunityBloodTest(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - positive_diagnosis_event(str, required): + positive_diagnosis_event (str, required): If the test has a positive diagnosis, this parameter defines the event to be broadcast to potentially trigger separate interventions or events. For HIV, see [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/), and for malaria, [Campaign event list](https://emod.idmod.org/emodpy-malaria/emod/parameter-campaign-event-list/) for events already used in EMOD or use your own custom event. - treatment_fraction(float, optional): + treatment_fraction (float, optional): The fraction of positive diagnoses that have the positive_diagnosis_event sent out to trigger separate interventions or events. Minimum value: 0 Maximum value: 1 Default value: 1 - positive_threshold_acquisition_immunity(float, optional): + positive_threshold_acquisition_immunity (float, optional): Specifies the threshold for acquired immunity, where 1 equals 100% immunity and 0 equals 100% susceptible. Minimum value: 0 Maximum value: 1 Default value: 1 - negative_diagnosis_event(str, optional): + negative_diagnosis_event (str, optional): If the test has a negative diagnosis, this parameter defines the event to be broadcast to potentially trigger separate interventions or events. For HIV, see [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/), and for malaria, [Campaign event list](https://emod.idmod.org/emodpy-malaria/emod/parameter-campaign-event-list/) for events already used in EMOD or @@ -433,7 +446,7 @@ class _ImmunityBloodTest(IndividualIntervention): If True, requires an infection to be symptomatic to return a positive test. Default value: False - days_to_diagnosis(float, optional): + days_to_diagnosis (float, optional): The number of days from the test, which is done when the intervention is distributed, until the positive_diagnosis_event is sent out if test had a positive diagnosis. The negative_diagnosis_event is sent out immediately if the test is negative. @@ -441,7 +454,7 @@ class _ImmunityBloodTest(IndividualIntervention): Maximum value: 3.40282e+38 Default value: 0 - base_specificity(float, optional): + base_specificity (float, optional): The specificity of the diagnostic. This sets the proportion of the time that individuals without the condition being tested receive a negative diagnostic test. When set to 1, the diagnostic always accurately reflects the lack of having the condition. When set to zero, then individuals who do not @@ -450,7 +463,7 @@ class _ImmunityBloodTest(IndividualIntervention): Maximum value: 1 Default value: 1 - base_sensitivity(float, optional): + base_sensitivity (float, optional): The sensitivity of the diagnostic. This sets the proportion of the time that individuals with the condition being tested receive a positive diagnostic test. When set to 1, the diagnostic always accurately reflects the condition. When set to zero, then individuals who have the condition always @@ -502,28 +515,28 @@ class IndividualImmunityChanger(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - prime_transmit(float, optional): + prime_transmit (float, optional): Specifies the priming effect on transmission immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - prime_mortality(float, optional): + prime_mortality (float, optional): Specifies the priming effect on mortality immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - prime_acquire(float, optional): + prime_acquire (float, optional): Specifies the priming effect on acquisition immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_transmit(float, optional): + boost_transmit (float, optional): Specifies the boosting effect on transmission immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -531,28 +544,28 @@ class IndividualImmunityChanger(IndividualIntervention): Maximum value: 1 Default value: 0 - boost_threshold_transmit(float, optional): + boost_threshold_transmit (float, optional): Specifies how much transmission immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_threshold_mortality(float, optional): + boost_threshold_mortality (float, optional): Specifies how much mortality immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_threshold_acquire(float, optional): + boost_threshold_acquire (float, optional): Specifies how much acquisition immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_mortality(float, optional): + boost_mortality (float, optional): Specifies the boosting effect on mortality immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -560,7 +573,7 @@ class IndividualImmunityChanger(IndividualIntervention): Maximum value: 1 Default value: 0 - boost_acquire(float, optional): + boost_acquire (float, optional): Specifies the boosting effect on acquisition immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -572,10 +585,12 @@ class IndividualImmunityChanger(IndividualIntervention): The CommonInterventionParameters object that contains the 1 common parameter: cost. The following parameters are not valid for this intervention: - intervention_name - dont_allow_duplicates - new_property_value - disqualifying_properties + + - intervention_name + - dont_allow_duplicates + - new_property_value + - disqualifying_properties + Default value: None """ @@ -644,6 +659,7 @@ class IndividualNonDiseaseDeathRateModifier(IndividualIntervention): determine when the person stops using the intervention. This is independent of how long the intervention is effective. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -653,6 +669,7 @@ class IndividualNonDiseaseDeathRateModifier(IndividualIntervention): * DualConstantDistribution * WeibullDistribution * DualExponentialDistribution + Default value: None common_intervention_parameters (CommonInterventionParameters, optional): @@ -684,11 +701,11 @@ class MigrateIndividuals(IndividualIntervention): As individuals migrate, there are three ways to categorize nodes: - - `Home`: the node where the individuals reside; each individual has a single home node. - - `Origin`: the "starting point" node for each leg of the migration. The origin updates - as individuals move between nodes. - - `Destination`: the node the individual is traveling to. The destination updates as - individuals move between nodes. + - Home: the node where the individuals reside; each individual has a single home node. + - Origin: the "starting point" node for each leg of the migration. The origin updates + as individuals move between nodes. + - Destination: the node the individual is traveling to. The destination updates as + individuals move between nodes. For example, Individual 1 has a home node of Node A. They migrate from Node A to Node B. Node A is both the home node and the origin node, and Node B is the destination node. @@ -701,23 +718,24 @@ class MigrateIndividuals(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - nodeid_to_migrate_to(int, optional): + nodeid_to_migrate_to (int, optional): The destination node ID for intervention-based migration. Minimum value: 0 Maximum value: 4294970000.0 Default value: 0 - is_moving(bool, optional): + is_moving (bool, optional): Set to True to indicate the individual is permanently moving to a new home node for intervention-based migration. Once at the new home node, trips will be made with this node as the root (i.e. round trips come back to this node). Default value: False - duration_before_leaving_distribution(BaseDistribution, optional): + duration_before_leaving_distribution (BaseDistribution, optional): The distribution type to use for assigning the duration of time an individual waits before migrating to the destination node after intervention-based migration. Each assigned value is a random draw from the distribution. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -727,13 +745,15 @@ class MigrateIndividuals(IndividualIntervention): * DualConstantDistribution * WeibullDistribution * DualExponentialDistribution + Default value: None - duration_at_node_distribution(BaseDistribution, optional): + duration_at_node_distribution (BaseDistribution, optional): The distribution type to use for assigning the duration of time an individual or family spends at a destination node after intervention-based migration. Each assigned value is a random draw from the distribution. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -743,13 +763,16 @@ class MigrateIndividuals(IndividualIntervention): * DualConstantDistribution * WeibullDistribution * DualExponentialDistribution + Default value: None common_intervention_parameters (CommonInterventionParameters, optional): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -788,19 +811,19 @@ class MultiEffectBoosterVaccine(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - transmit_config(AbstractWaningConfig, required): + transmit_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine transmission. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - mortality_config(AbstractWaningConfig, required): + mortality_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine mortality. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - acquire_config(AbstractWaningConfig, required): + acquire_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine acquisition. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - vaccine_take(float, optional): + vaccine_take (float, optional): The rate at which delivered vaccines will successfully stimulate an immune response and achieve the desired efficacy. For example, if it is set to 0.9, there will be a 90 percent chance that the vaccine will start with the specified efficacy, and a 10 percent chance that it will have no @@ -809,28 +832,28 @@ class MultiEffectBoosterVaccine(IndividualIntervention): Maximum value: 1 Default value: 1 - prime_transmit(float, optional): + prime_transmit (float, optional): Specifies the priming effect on transmission immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - prime_mortality(float, optional): + prime_mortality (float, optional): Specifies the priming effect on mortality immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - prime_acquire(float, optional): + prime_acquire (float, optional): Specifies the priming effect on acquisition immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_transmit(float, optional): + boost_transmit (float, optional): Specifies the boosting effect on transmission immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -838,28 +861,28 @@ class MultiEffectBoosterVaccine(IndividualIntervention): Maximum value: 1 Default value: 0 - boost_threshold_transmit(float, optional): + boost_threshold_transmit (float, optional): Specifies how much transmission immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_threshold_mortality(float, optional): + boost_threshold_mortality (float, optional): Specifies how much mortality immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_threshold_acquire(float, optional): + boost_threshold_acquire (float, optional): Specifies how much acquisition immunity is required before the vaccine changes from a prime to a boost. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_mortality(float, optional): + boost_mortality (float, optional): Specifies the boosting effect on mortality immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -867,7 +890,7 @@ class MultiEffectBoosterVaccine(IndividualIntervention): Maximum value: 1 Default value: 0 - boost_acquire(float, optional): + boost_acquire (float, optional): Specifies the boosting effect on acquisition immunity for naive individuals (without natural or vaccine-derived immunity) for a multi-effect booster vaccine. This does not replace current immunity, it builds multiplicatively on top of it. @@ -925,9 +948,9 @@ class MultiEffectVaccine(IndividualIntervention): The **MultiEffectVaccine** intervention class implements vaccine campaigns in the simulation. Vaccines can affect all of the following: - - Reduce the likelihood of acquiring an infection - - Reduce the likelihood of transmitting an infection - - Reduce the likelihood of death + - Reduce the likelihood of acquiring an infection + - Reduce the likelihood of transmitting an infection + - Reduce the likelihood of death After distribution, the effect wanes over time. @@ -935,19 +958,19 @@ class MultiEffectVaccine(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - transmit_config(AbstractWaningConfig, required): + transmit_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine transmission. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - mortality_config(AbstractWaningConfig, required): + mortality_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine mortality. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - acquire_config(AbstractWaningConfig, required): + acquire_config (AbstractWaningConfig, required): The configuration for multi-effect vaccine acquisition. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - vaccine_take(float, optional): + vaccine_take (float, optional): The rate at which delivered vaccines will successfully stimulate an immune response and achieve the desired efficacy. For example, if it is set to 0.9, there will be a 90 percent chance that the vaccine will start with the specified efficacy, and a 10 percent chance that it will have no @@ -992,14 +1015,16 @@ class MultiInterventionDistributor(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - intervention_list(list[IndividualIntervention], required): + intervention_list (list[IndividualIntervention], required): The list of individual interventions that is distributed by **MultiInterventionDistributor**. common_intervention_parameters (CommonInterventionParameters, optional): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. - The following parameters are not valid for this intervention: - cost + The following parameters are not valid for this intervention + + - cost + Default value: None """ @@ -1025,7 +1050,7 @@ class OutbreakIndividual(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - incubation_period_override(int, optional): + incubation_period_override (int, optional): The incubation period, in days, that infected individuals will go through before becoming infectious. This value overrides the incubation period set in the configuration file. Note for HIV simulations only: If set to 0, infection is assumed to be part of an outbreak event and a random @@ -1035,19 +1060,19 @@ class OutbreakIndividual(IndividualIntervention): Maximum value: 2147480000.0 Default value: -1 - ignore_immunity(bool, optional): + ignore_immunity (bool, optional): Individuals will be force-infected (with a specific strain) regardless of actual immunity level when set to True. Default value: True - genome(int, optional): + genome (int, optional): The genetic substrain ID of the outbreak infection. Together with **Antigen**, they are a unitary object representing a strain of infection, which allows for differentiation among infections. Minimum value: -1 Maximum value: 16777200.0 Default value: 0 - antigen(int, optional): + antigen (int, optional): The antigenic base strain ID of the outbreak infection. Minimum value: 0 Maximum value: 10 @@ -1099,13 +1124,13 @@ class PropertyValueChanger(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - target_property_value(str, required): + target_property_value (str, required): The user-defined value of the individual property that will be assigned to the individual. - target_property_key(str, required): + target_property_key (str, required): The name of the individual property type whose value will be updated by the intervention. - revert(float, optional): + revert (float, optional): The number of days to keep the value (**Target_Property_Value**) of the property (**Target_Property_Key**) set by the intervention for the individual. When the time has expired, the intervention will reset the property back to the value it had when the intervention was first @@ -1114,7 +1139,7 @@ class PropertyValueChanger(IndividualIntervention): Maximum value: 3.40282e+38 Default value: 0 - maximum_duration(float, optional): + maximum_duration (float, optional): The maximum amount of time individuals have to move to a new group. This timing works in conjunction with **Daily_Probability**. Minimum value: -1 @@ -1131,7 +1156,9 @@ class PropertyValueChanger(IndividualIntervention): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -1172,20 +1199,22 @@ class SimpleBoosterVaccine(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - waning_config(AbstractWaningConfig, required): + waning_config (AbstractWaningConfig, required): The configuration of the vaccine's efficacy and waning over time. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - vaccine_type(VaccineType, optional): + vaccine_type (VaccineType, optional): The type of vaccine to distribute in a vaccine intervention. Possible values are: + * Generic - The vaccine can reduce transmission, acquisition, and mortality. * TransmissionBlocking - The vaccine will reduce pathogen transmission. * AcquisitionBlocking - The vaccine will reduce the acquisition of the pathogen by reducing the force of infection experienced by the vaccinated individual. * MortalityBlocking - The vaccine reduces the disease-mortality rate of a vaccinated individual. + Default value: Generic - vaccine_take(float, optional): + vaccine_take (float, optional): The rate at which delivered vaccines will successfully stimulate an immune response and achieve the desired efficacy. For example, if it is set to 0.9, there will be a 90 percent chance that the vaccine will start with the specified efficacy, and a 10 percent chance that it will have no @@ -1194,26 +1223,26 @@ class SimpleBoosterVaccine(IndividualIntervention): Maximum value: 1 Default value: 1 - prime_effect(float, optional): + prime_effect (float, optional): Specifies the priming effect on [acquisition/transmission/mortality] immunity for naive individuals (without natural or vaccine-derived immunity). Minimum value: 0 Maximum value: 1 Default value: 1 - efficacy_is_multiplicative(bool, optional): + efficacy_is_multiplicative (bool, optional): The overall vaccine efficacy when individuals receive more than one vaccine. When set to True, the vaccine efficacies are multiplied together; when set to False, the efficacies are additive. Default value: True - boost_threshold(float, optional): + boost_threshold (float, optional): Specifies how much immunity is required before the vaccine changes from a priming effect to a boosting effect. Minimum value: 0 Maximum value: 1 Default value: 0 - boost_effect(float, optional): + boost_effect (float, optional): Specifies the boosting effect on [acquisition/transmission/mortality] immunity for previously exposed individuals (either natural or vaccine-derived). This does not replace current immunity, it builds multiplicatively on top of it. @@ -1264,30 +1293,30 @@ class _SimpleDiagnostic(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - positive_diagnosis_config(IndividualIntervention, optional): + positive_diagnosis_config (IndividualIntervention, optional): The intervention distributed to individuals if they test positive. Must be defined if not using positive_diagnosis_event. Cannot have both positive_diagnosis_config and positive_diagnosis_event. Default value: None - positive_diagnosis_event(str, optional): + positive_diagnosis_event (str, optional): If the test is positive, this specifies an event that can trigger another intervention when the event occurs. Must be defined if not using positive_diagnosis_config. Cannot have both positive_diagnosis_config and positive_diagnosis_event. For HIV, see [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/), and for malaria, [Campaign event list](https://emod.idmod.org/emodpy-malaria/emod/parameter-campaign-event-list/) for events already used in EMOD or use your own custom event. Default value: None - treatment_fraction(float, optional): + treatment_fraction (float, optional): The fraction of positive diagnoses that are given the positive_diagnosis_config or positive_diagnosis_event, whichever is defined. Minimum value: 0 Maximum value: 1 Default value: 1 - enable_is_symptomatic(bool, optional): + enable_is_symptomatic (bool, optional): If True, requires an infection to be symptomatic to return a positive test. Default value: False - days_to_diagnosis(float, optional): + days_to_diagnosis (float, optional): The number of days from diagnosis (which is done when the intervention is distributed) until a positive response is performed. The response to a negative diagnosis is done immediately when the diagnosis is made (at distribution of the intervention). @@ -1295,7 +1324,7 @@ class _SimpleDiagnostic(IndividualIntervention): Maximum value: 3.40282e+38 Default value: 0 - base_specificity(float, optional): + base_specificity (float, optional): The specificity of the diagnostic. This sets the proportion of the time that individuals without the condition being tested receive a negative diagnostic test. When set to 1, the diagnostic always accurately reflects the lack of having the condition. When set to zero, then individuals who do not @@ -1304,7 +1333,7 @@ class _SimpleDiagnostic(IndividualIntervention): Maximum value: 1 Default value: 1 - base_sensitivity(float, optional): + base_sensitivity (float, optional): The sensitivity of the diagnostic. This sets the proportion of the time that individuals with the condition being tested receive a positive diagnostic test. When set to 1, the diagnostic always accurately reflects the condition. When set to zero, then individuals who have the condition always @@ -1371,24 +1400,24 @@ class _SimpleHealthSeekingBehavior(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - intervention_config(IndividualIntervention, optional): + intervention_config (IndividualIntervention, optional): The configuration for the IndividualIntervention that the individual will receive after the delay. Default value: None - intervention_event(str, optional): + intervention_event (str, optional): The name of the event to broadcast when individual has been selected to receive care after the delay. For HIV, see [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/), and for malaria, [Campaign event list](https://emod.idmod.org/emodpy-malaria/emod/parameter-campaign-event-list/) for events already used in EMOD or use your own custom event. Default value: None - tendency(float, optional): + tendency (float, optional): The probability of seeking healthcare. Minimum value: 0 Maximum value: 1 Default value: 1 - single_use(bool, optional): + single_use (bool, optional): If set to True, the health-seeking behavior gets used once and discarded. If set to False, it remains indefinitely. Default value: True @@ -1397,7 +1426,9 @@ class _SimpleHealthSeekingBehavior(IndividualIntervention): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, new_property_value, dont_allow_duplicates, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -1436,9 +1467,9 @@ class SimpleVaccine(IndividualIntervention): The **SimpleVaccine** intervention class implements vaccine campaigns in the simulation. Vaccines can have an effect on one of the following: - - Reduce the likelihood of acquiring an infection - - Reduce the likelihood of transmitting an infection - - Reduce the likelihood of death + - Reduce the likelihood of acquiring an infection + - Reduce the likelihood of transmitting an infection + - Reduce the likelihood of death To configure vaccines that have an effect on more than one of these, use **MultiEffectVaccine** instead. @@ -1446,20 +1477,22 @@ class SimpleVaccine(IndividualIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - waning_config(AbstractWaningConfig, required): + waning_config (AbstractWaningConfig, required): The configuration of the vaccine's efficacy and waning over time. Specify how this effect decays over time using one of the Waning Config classes in emodpy.campaign.waning_config. - vaccine_type(VaccineType, optional): + vaccine_type (VaccineType, optional): The type of vaccine to distribute in a vaccine intervention. Possible values are: + * Generic - The vaccine can reduce transmission, acquisition, and mortality. * TransmissionBlocking - The vaccine will reduce pathogen transmission. * AcquisitionBlocking - The vaccine will reduce the acquisition of the pathogen by reducing the force of infection experienced by the vaccinated individual. * MortalityBlocking - The vaccine reduces the disease-mortality rate of a vaccinated individual. + Default value: Generic - vaccine_take(float, optional): + vaccine_take (float, optional): The rate at which delivered vaccines will successfully stimulate an immune response and achieve the desired efficacy. For example, if it is set to 0.9, there will be a 90 percent chance that the vaccine will start with the specified efficacy, and a 10 percent chance that it will have no @@ -1468,7 +1501,7 @@ class SimpleVaccine(IndividualIntervention): Maximum value: 1 Default value: 1 - efficacy_is_multiplicative(bool, optional): + efficacy_is_multiplicative (bool, optional): The overall vaccine efficacy when individuals receive more than one vaccine. When set to True, the vaccine efficacies are multiplied together; when set to False, the efficacies are additive. Default value: True @@ -1512,19 +1545,19 @@ class StandardDiagnostic(IndividualIntervention): campaign (api_campaign, required): - An instance of the emod_api.campaign module. - positive_diagnosis_config(IndividualIntervention, optional): + positive_diagnosis_config (IndividualIntervention, optional): - The intervention distributed to individuals if they test positive. - Must be defined if not using positive_diagnosis_event. - Cannot have both positive_diagnosis_config and positive_diagnosis_event. - Default value: None - negative_diagnosis_config(IndividualIntervention, optional): + negative_diagnosis_config (IndividualIntervention, optional): - The intervention distributed to individuals if they test negative. - If using positive_diagnosis_config, you can use negative_diagnosis_config, but not negative_diagnosis_event. - Can use this or negative_diagnosis_event, but not both. - Default value: None - positive_diagnosis_event(str, optional): + positive_diagnosis_event (str, optional): - If the test is positive, this specifies an event that can trigger another intervention when the event occurs. - Must be defined if not using positive_diagnosis_config. - Cannot have both positive_diagnosis_config and positive_diagnosis_event. @@ -1538,7 +1571,7 @@ class StandardDiagnostic(IndividualIntervention): - For HIV, see [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/), and for malaria, [Campaign event list](https://emod.idmod.org/emodpy-malaria/emod/parameter-campaign-event-list/) for events already used in EMOD or use your own custom event. - Default value: None - treatment_fraction(float, optional): + treatment_fraction (float, optional): - The fraction of positive diagnoses that are given the positive_diagnosis_config or positive_diagnosis_event, whichever is defined. This does not affect the distribution of the negative diagnosis. @@ -1546,11 +1579,11 @@ class StandardDiagnostic(IndividualIntervention): - Maximum value: 1 - Default value: 1 - enable_is_symptomatic(bool, optional): + enable_is_symptomatic (bool, optional): - If True, requires an infection to be symptomatic to return a positive test. - Default value: False - days_to_diagnosis(float, optional): + days_to_diagnosis (float, optional): - The number of days from the test, which is done when the intervention is distributed, until the positive_diagnosis_config or positive_diagnosis_event (whichever is defined) are distributed if the test had a positive diagnosis. The negative_diagnosis_config or negative_diagnosis_event is distributed @@ -1559,7 +1592,7 @@ class StandardDiagnostic(IndividualIntervention): - Maximum value: 3.40282e+38 - Default value: 0 - base_specificity(float, optional): + base_specificity (float, optional): - The specificity of the diagnostic. This sets the proportion of the time that individuals without the condition being tested receive a negative diagnostic test. When set to 1, the diagnostic always accurately reflects the lack of having the condition. When set to zero, then individuals who do not @@ -1568,7 +1601,7 @@ class StandardDiagnostic(IndividualIntervention): - Maximum value: 1 - Default value: 1 - base_sensitivity(float, optional): + base_sensitivity (float, optional): - The sensitivity of the diagnostic. This sets the proportion of the time that individuals with the condition being tested receive a positive diagnostic test. When set to 1, the diagnostic always accurately reflects the condition. When set to zero, then individuals who have the condition always diff --git a/emodpy/campaign/node_intervention.py b/emodpy/campaign/node_intervention.py index edeb562..1f2861f 100644 --- a/emodpy/campaign/node_intervention.py +++ b/emodpy/campaign/node_intervention.py @@ -30,7 +30,9 @@ class MultiNodeInterventionDistributor(NodeIntervention): The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, dont_allow_duplicates, new_property_value, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -58,7 +60,7 @@ class _NodeLevelHealthTriggeredIV(NodeIntervention): become infected, they broadcast the 'NewInfectionEvent' trigger and **NodeLevelHealthTriggeredIV** distributes the diagnostic intervention to them. - Notes and tips for this intervention: + Notes and tips for this intervention - This is the main tool for distributing an intervention to a person when an event happens to that person. Note that the intervention is distributed to all individuals in the node which experience the triggering @@ -91,11 +93,11 @@ class _NodeLevelHealthTriggeredIV(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - intervention_list(list[Union[NodeIntervention, IndividualIntervention], required): + intervention_list (list[Union[NodeIntervention, IndividualIntervention], required): The configuration of an actual individual intervention to be distributed on the trigger. Selects a class for the intervention and configures the parameters specific for that intervention class. - trigger_condition_list(list[str], required): + trigger_condition_list (list[str], required): A list of individual events that will trigger the distribution of the intervention. The events in the list must either be events already used in EMOD or custom events defined to be distributed elsewhere in the campaign. See [Campaign event list](https://emod.idmod.org/emodpy-hiv/emod/parameter-campaign-event-list/) for events already used in EMOD. @@ -107,29 +109,29 @@ class for the intervention and configures the parameters specific for that inter information. Default value: None - property_restrictions(PropertyRestrictions, optional): + property_restrictions (PropertyRestrictions, optional): A PropertyRestrictions object that can be used to restrict the distribution of the intervention to individuals or nodes with specific properties. Please see [PropertyRestrictions][emodpy.campaign.common.PropertyRestrictions] for more information. Default value: None - targeting_config(AbstractTargetingConfig, optional): + targeting_config (AbstractTargetingConfig, optional): Be more selective of individuals by using the emodpy.utils.targeting_config classes. Please refer to the emodpy.utils.targeting_config for more information. - duration(float, optional): + duration (float, optional): The number of days to continue this intervention. It will listen and respond to events during this time. A value of -1 (the default) keeps the intervention running indefinitely. Minimum value: -1 Maximum value: 3.40282e+38 Default value: -1 - distribute_on_return_home(bool, optional): + distribute_on_return_home (bool, optional): When set to True, individuals will receive an intervention upon returning home if that intervention was originally distributed while the individual was away. Default value: False - blackout_period(float, optional): + blackout_period (float, optional): After the initial intervention distribution, the time, in days, to wait before distributing the intervention again. If it cannot distribute due to the blackout period, it will broadcast the user-defined blackout_event_trigger. @@ -137,7 +139,7 @@ class for the intervention and configures the parameters specific for that inter Maximum value: 3.40282e+38 Default value: 0 - blackout_on_first_occurrence(bool, optional): + blackout_on_first_occurrence (bool, optional): If set to True, individuals will enter the blackout period after the first occurrence of an event in the trigger_condition_list. Default value: True @@ -150,7 +152,9 @@ class for the intervention and configures the parameters specific for that inter The CommonInterventionParameters object that contains the 4 common parameters: intervention_name, dont_allow_duplicates, new_property_value, disqualifying_properties. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -238,25 +242,25 @@ class _BirthTriggeredIV(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - intervention_config(IndividualIntervention, required): + intervention_config (IndividualIntervention, required): The configuration of an actual individual intervention to be distributed on the trigger. Selects a class for the intervention and configures the parameters specific for that intervention class. - target_demographics_config(TargetDemographicsConfig, optional): + target_demographics_config (TargetDemographicsConfig, optional): The TargetDemographicsConfig object that is used to configure the demographics of the targeted individuals, for example: Demographic_Coverage, Target_Demographic, Target_Age_Min, Target_Age_Max, Target_Gender and Target_Residents_Only. Please refer to [TargetDemographicsConfig][emodpy.campaign.common.TargetDemographicsConfig] for more information. Default value: None - property_restrictions(PropertyRestrictions, optional): + property_restrictions (PropertyRestrictions, optional): A PropertyRestrictions object that can be used to restrict the distribution of the intervention to individuals with specific properties. Please see [PropertyRestrictions][emodpy.campaign.common.PropertyRestrictions] for more information. This intervention only supports individual property restrictions (Property_Restrictions, Property_Restrictions_Within_Node), not node property restrictions. Default value: None - duration(float, optional): + duration (float, optional): The number of days to continue this intervention. It will listen and respond to events during this time. A value of -1 (the default) keeps the intervention running indefinitely. Minimum value: -1 @@ -267,7 +271,9 @@ class for the intervention and configures the parameters specific for that inter The CommonInterventionParameters object that contains the 4 common parameters: disqualifying_properties, dont_allow_duplicates, intervention_name, new_property_value. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -335,7 +341,9 @@ class BroadcastCoordinatorEventFromNode(NodeIntervention): The CommonInterventionParameters object that contains the 4 common parameters: disqualifying_properties, dont_allow_duplicates, intervention_name, new_property_value. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -404,11 +412,11 @@ class ImportPressure(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - durations(list[int], required): + durations (list[int], required): The durations over which to apply import pressure. Must be a non-empty list and must have the same length as **daily_import_pressures**. - daily_import_pressures(list[float], required): + daily_import_pressures (list[float], required): The rate of per-day importation for each node that the intervention is distributed to. Must be a non-empty list and must have the same length as **durations**. @@ -418,19 +426,26 @@ class ImportPressure(NodeIntervention): Maximum value: 43800 Default value: 365 - genome(int, optional): + genome (int, optional): The genetic substrain ID of the outbreak infection. Together with **Antigen**, they are a unitary object representing a strain of infection, which allows for differentiation among infections. Minimum value: -1 Maximum value: 16777200.0 Default value: 0 - antigen(int, optional): + durations (list[int], optional): + The durations over which to apply import pressure. + Default value: None + + daily_import_pressures (list[float], optional): + The rate of per-day importation for each node that the intervention is distributed to. + Default value: None + + antigen (int, optional): The antigenic base strain ID of the outbreak infection. Minimum value: 0 Maximum value: 10 Default value: 0 - """ def __init__(self, @@ -488,11 +503,12 @@ class MigrateFamily(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - duration_before_leaving_distribution(BaseDistribution, required): + duration_before_leaving_distribution (BaseDistribution, required): The distribution type to use for assigning the duration of time a family waits before migrating to the destination node after all residents are home. Each assigned value is a random draw from the distribution. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -503,11 +519,12 @@ class MigrateFamily(NodeIntervention): * WeibullDistribution * DualExponentialDistribution - duration_at_node_distribution(BaseDistribution, required): + duration_at_node_distribution (BaseDistribution, required): The distribution type to use for assigning the duration of time an individual or family spends at a destination node after intervention-based migration. Each assigned value is a random draw from the distribution. Please use the following distribution classes from emodpy.utils.distributions to define the distribution: + * ConstantDistribution * UniformDistribution * GaussianDistribution @@ -518,13 +535,13 @@ class MigrateFamily(NodeIntervention): * WeibullDistribution * DualExponentialDistribution - nodeid_to_migrate_to(int, required): + nodeid_to_migrate_to (int, required): The destination node ID for intervention-based migration. Minimum value: 0 Maximum value: 4294970000.0 Default value: 0 - is_moving(bool, optional): + is_moving (bool, optional): Set to true (1) to indicate all the individuals of the family are permanently moving to a new home node for intervention-based migration. Once at the new home node, trips will be made with this node as the root (i.e. round trips come back to this node). @@ -534,7 +551,9 @@ class MigrateFamily(NodeIntervention): The CommonInterventionParameters object that contains the 4 common parameters: disqualifying_properties, dont_allow_duplicates, intervention_name, new_property_value. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -568,10 +587,10 @@ class NodePropertyValueChanger(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - target_np_key_value(str, required): + target_np_key_value (str, required): The **NodeProperty** key:value pair, as defined in the demographics file, to assign to the node. - revert(float, optional): + revert (float, optional): The number of days to keep the value of the property/key, specified in **Target_NP_Key_Value** and set by the intervention, for the node. When the time has expired, the intervention will reset the property/key back to the value it had when the intervention was first applied. @@ -579,14 +598,14 @@ class NodePropertyValueChanger(NodeIntervention): Maximum value: 3.40282e+38 Default value: 3.40282e+38 - maximum_duration(float, optional): + maximum_duration (float, optional): The maximum amount of time in days nodes have to update the property value. This timing works in conjunction with **Daily_Probability**. Minimum value: -1 Maximum value: 3.40282e+38 Default value: 3.40282e+38 - daily_probability(float, optional): + daily_probability (float, optional): The daily probability that the node's property value changes to the **Target_NP_Key_Value**. Minimum value: 0 Maximum value: 1 @@ -596,7 +615,9 @@ class NodePropertyValueChanger(NodeIntervention): The CommonInterventionParameters object that contains the 4 common parameters: disqualifying_properties, dont_allow_duplicates, intervention_name, new_property_value. The following parameters are not valid for this intervention: - cost + + - cost + Default value: None """ @@ -628,40 +649,38 @@ class Outbreak(NodeIntervention): campaign (api_campaign, required): An instance of the emod_api.campaign module. - probability_of_infection(float, optional): + probability_of_infection (float, optional): The probability that new individuals are infected. 1.0 implies all new individuals are infected while 0.0 adds all of the people as susceptible individuals. Minimum value: 0 Maximum value: 1 Default value: 1 - number_cases_per_node(int, optional): - The number of new imported individuals. - .. note:: This will increase the population with demographics of 50/50 male/female and user-defined - ages + number_cases_per_node (int, optional): + The number of new imported individuals. Note, this will increase the population with demographics of + 50/50 male/female and user-defined ages. Minimum value: 0 Maximum value: 2147480000.0 Default value: 1 - import_age(float, optional): + import_age (float, optional): The age (in days) of infected import cases. Minimum value: 0 Maximum value: 43800 Default value: 365 - genome(int, optional): + genome (int, optional): The genetic substrain ID of the outbreak infection. Together with **Antigen**, they are a unitary object representing a strain of infection, which allows for differentiation among infections. Minimum value: -1 Maximum value: 16777200.0 Default value: 0 - antigen(int, optional): + antigen (int, optional): The antigenic base strain ID of the outbreak infection. Minimum value: 0 Maximum value: 10 Default value: 0 - """ def __init__(self, diff --git a/emodpy/emod_file.py b/emodpy/emod_file.py index 6f7db4a..d204c4c 100644 --- a/emodpy/emod_file.py +++ b/emodpy/emod_file.py @@ -24,10 +24,7 @@ def set_task_config(self, simulation): def gather_assets(self) -> List[Asset]: """ - Gather input files for Input File List - - Returns: - + Gather input files for Input File List. """ assets = [a for a in self.assets if not a.persisted] for a in assets: @@ -51,8 +48,8 @@ def __init__(self, relative_path=None): def enable_migration(self): """ - Enables migration and sets the pattern if defined. If there are not other other parameters, it also set - *Enable_Migration_Heterogeneity* to 0 + Enables migration and sets the pattern if defined. If there are no other parameters, it also sets + *Enable_Migration_Heterogeneity* to 0. """ self.migration_model = MigrationModel.FIXED_RATE_MIGRATION if not self.migration_pattern: @@ -62,14 +59,12 @@ def enable_migration(self): def update_migration_pattern(self, migration_pattern: MigrationPattern, **kwargs: Any) -> None: """ - Update migration pattern + Update migration pattern. Args: - migration_pattern: Migration Pattern to use - **kwargs: - - Returns: - None + migration_pattern (MigrationPattern): Migration Pattern to use + **kwargs (Any): Additional migration parameters supplied as keyword + arguments (for example `Enable_Migration_Heterogeneity=1`). """ self.enable_migration() self.migration_pattern = migration_pattern @@ -78,15 +73,12 @@ def update_migration_pattern(self, migration_pattern: MigrationPattern, **kwargs def add_migration_from_file(self, migration_type: MigrationType, file_path: str, multiplier: float = 1): """ - Add migration info from a file + Add migration info from a file. Args: - migration_type: Type of migration - file_path: Path to file - multiplier: Multiplier - - Returns: - + migration_type (MigrationTypes): Type of migration + file_path (str): Path to file + multiplier (float): Multiplier """ self.enable_migration() asset = Asset(absolute_path=file_path, relative_path=self.relative_path) @@ -97,13 +89,10 @@ def add_migration_from_file(self, migration_type: MigrationType, file_path: str, def set_task_config(self, task: 'EMODTask'): """ - Update the task with the migration configuration + Update the task with the migration configuration. Args: - task: Task to update - - Returns: - + task (EMODTask): Task to update """ # Set the migration model if present if self.migration_model: @@ -135,9 +124,7 @@ def set_task_config(self, task: 'EMODTask'): def gather_assets(self): """ - Gather assets for Migration files. Called by EMODTask - Returns: - + Gather assets for Migration files. Called by EMODTask. """ for asset in self.migration_files.values(): if asset.persisted: @@ -150,10 +137,7 @@ def gather_assets(self): def set_all_persisted(self): """ - Set akk migration assets as persisted - - Returns: - + Set all migration assets as persisted. """ for asset in self.migration_files.values(): asset.persisted = True @@ -161,14 +145,11 @@ def set_all_persisted(self): def merge_with(self, mf: 'MigrationFiles', left_precedence: bool = True) -> None: """ - Merge migration file with other Migration file + Merge migration file with other Migration file. Args: - mf: Other migration file to merge with - left_precedence: Does the current object have precedence or the other object? - - Returns: - None + mf (MigrationFiles): Other migration file to merge with. + left_precedence (bool): Does the current object have precedence or the other object? """ if not left_precedence: self.migration_files.update(mf.migration_files) @@ -191,10 +172,10 @@ def merge_with(self, mf: 'MigrationFiles', left_precedence: bool = True) -> None def read_config_file(self, config_path, asset_path): """ - Try to recreate the migration based on a given config file and an asset path + Try to recreate the migration based on a given config file and an asset path. Args: - config_path: path to the config - asset_path: path containing the assets + config_path: path to the config. + asset_path: path containing the assets. """ config = json.load(open(config_path)) params = config["parameters"] @@ -218,13 +199,11 @@ def read_config_file(self, config_path, asset_path): class DemographicsFiles(InputFilesList): def set_task_config(self, task: 'EMODTask', extend: bool = False): """ - Set the simulation level config. If extend is true, the demographics files are appended to the list - Args: - task: - extend: - - Returns: + Set the simulation level config. If `extend` is true, the demographics files are appended to the list. + Args: + task (EMODTask): The task to update. + extend (bool): If true, the demographics files are appended to the list. """ dfiles = [os.path.join(df.relative_path, df.filename) for df in self.assets] if dfiles: @@ -240,13 +219,12 @@ def set_task_config(self, task: 'EMODTask', extend: bool = False): def add_demographics_from_files(self, absolute_path: str, filename: Optional[str] = None): """ - Add demographics files into the demographics.assets from a file or from a directory + Add demographics files into the demographics.assets from a file or from a directory. Args: - absolute_path: Path to file, including the filename or folder. All .json files in the folder + absolute_path (str): Path to file, including the filename or folder. All .json files in the folder will be added as demographics files and used in the experiment. - filename: Optional filename. If not provided, the file name of source file will be used - + filename (str): Optional filename. If not provided, the file name of source file will be used. """ filename = filename or os.path.basename(absolute_path) @@ -275,14 +253,11 @@ def add_asset(file_name, abs_path): def add_demographics_from_dict(self, content: Dict, filename: str): """ - Add demographics from a dictionary object + Add demographics from a dictionary object. Args: - content: Dictionary Content - filename: Filename to call demographics file - - Returns: - + content (Dict): Dictionary Content. + filename (str): Filename to call demographics file. """ asset = Asset(filename=filename, content=content, relative_path=self.relative_path, handler=json_handler) if asset in self.assets: @@ -320,7 +295,7 @@ def set_task_config(self, task: 'EMODTask'): Set the task Config. Set all the correct files for the climate. Args: - task: Task to config + task (EMODTask): Task to config. """ # Set the files for climate_type, asset in self.files_by_type.items(): @@ -351,7 +326,7 @@ def add_climate_files(self, file_type, file_path): def gather_assets(self): """ - Gather assets for Climate files. Called by EMODTask + Gather assets for Climate files. Called by EMODTask. """ # Skip if the climate model is not by data if self.Climate_Model != ClimateModel.CLIMATE_BY_DATA: @@ -380,12 +355,13 @@ def set_climate_constant(self, Base_Air_Temperature, Base_Rainfall, Base_Land_Te self.climate_params[ "Base_Relative_Humidity"] = Base_Relative_Humidity if Base_Relative_Humidity is not None else .1 - def read_config_file(self, config_path, asset_path): + def read_config_file(self, config_path: str, asset_path: str): """ - Try to recreate the climate based on a given config file and an asset path + Try to recreate the climate based on a given config file and an asset path. + Args: - config_path: path to the config - asset_path: path containing the assets + config_path (str): path to the config + asset_path (str): path containing the assets """ config = json.load(open(config_path)) params = config["parameters"] diff --git a/emodpy/emod_task.py b/emodpy/emod_task.py index 927f6d2..e0dc7a1 100644 --- a/emodpy/emod_task.py +++ b/emodpy/emod_task.py @@ -144,35 +144,33 @@ def create_campaign_from_callback(self, builder: Callable, verbose: bool = False adding them to the config. Args: - builder: Function that creates and adds interventions to the campaign module. The function needs to take + builder (Callable): Function that creates and adds interventions to the campaign module. The function needs to take the campaign module as the first required argument, which can then be followed by parameters that you want to modify within the interventions. These additional parameters are then available to be modified in a sweep. The function must return the campaign module at the end. - Example:: - - def campaign_builder(campaign, another_param=0.3): - from emodpy.campaign.individual_intervention import CommonInterventionParameters, SimpleVaccine, VaccineType - from emodpy.campaign.distributor import add_intervention_scheduled - import emodpy.campaign.waning_config as waning_config - - this_waning_config = waning_config.BoxExponential(25, 60, 0.89) - common_intervention_parameters = CommonInterventionParameters(cost=0.5, - dont_allow_duplicates=True) - vaccine = SimpleVaccine(campaign, - waning_config=this_waning_config, - vaccine_take=another_param, - vaccine_type=VaccineType.TransmissionBlocking, - common_intervention_parameters=common_intervention_parameters) - add_intervention_scheduled(campaign, intervention_list=[vaccine], start_day=2) - return campaign - - verbose: If True, prints debug information about the generated file. - bootstrapped: Set to True if the campaign builder will build a campaign from scratch itself. False if it + Example: + + ``` + def campaign_builder(campaign, another_param=0.3): + from emodpy.campaign.individual_intervention import CommonInterventionParameters, SimpleVaccine, VaccineType + from emodpy.campaign.distributor import add_intervention_scheduled + import emodpy.campaign.waning_config as waning_config + + this_waning_config = waning_config.BoxExponential(25, 60, 0.89) + common_intervention_parameters = CommonInterventionParameters(cost=0.5, + dont_allow_duplicates=True) + vaccine = SimpleVaccine(campaign, + waning_config=this_waning_config, + vaccine_take=another_param, + vaccine_type=VaccineType.TransmissionBlocking, + common_intervention_parameters=common_intervention_parameters) + add_intervention_scheduled(campaign, intervention_list=[vaccine], start_day=2) + return campaign + ``` + verbose (bool): If True, prints debug information about the generated file. + bootstrapped (bool): Set to True if the campaign builder will build a campaign from scratch itself. False if it will accept an initialized campaign from this function instead and then modify it. Default False. - - Returns: - None """ if builder is None: return @@ -222,12 +220,9 @@ def create_demographics_from_callback(self, builder: Callable, Creates a demographics file using a builder function and manages its storage. Args: - builder: A function that generates the demographics object. + builder (Callable): A function that generates the demographics object. from_sweep (bool): If True, the demographics file is stored in a temporary location. verbose (bool): If True, prints debug information about the generated file. - - Returns: - None """ # If no builder function is provided, exit early. if builder is None: @@ -283,9 +278,6 @@ def create_demographics_from_callback(self, builder: Callable, def handle_implicit_configs(self) -> None: """ Execute the implicit config functions created by the demographics builder. - - Returns: - None """ if dev_mode: logger.debug(f"Executing {len(self.implicit_configs)} implicit config functions from demographics and " @@ -332,10 +324,10 @@ def build_default_config(schema_path: Union[str, Path]) -> ReadOnlyDict: Build the default config object from the schema. Args: - schema_path: Path to the schema file. + schema_path (Union[str, Path]): Path to the schema file. Returns: - ReadOnlyDict: The default config based on the schema. + ReadOnlyDict (ReadOnlyDict): The default config based on the schema. """ default_config = dfs.get_default_config_from_schema(path_to_schema=schema_path, as_rod=True) # needed by emodpy_hiv.country_model.build_config @@ -348,10 +340,10 @@ def build_default_campaign(schema_path: Union[str, Path]) -> api_campaign: Build the default (empty) campaign and set its schema_path. Args: - schema_path: Path to the schema file. + schema_path (Union[str, Path]): Path to the schema file. Returns: - Fresh initialized campaign module with schema_path set + api_campaign (api_campaign): Fresh initialized campaign module with schema_path set. """ api_campaign.set_schema(schema_path_in=schema_path) return api_campaign @@ -371,93 +363,94 @@ def from_defaults(cls, Create a task from emod-api defaults and functions to update them. Args: - schema_path: Path to processed schema.json, including the filename. - eradication_path: Path to Eradication binary, including the filename. You can also add Eradication as an + schema_path (str): Path to processed schema.json, including the filename. + eradication_path (str): Path to Eradication binary, including the filename. You can also add Eradication as an asset. - config_builder: Function that sets parameters for config. The function must have config object as the + config_builder (Callable): Function that sets parameters for config. The function must have config object as the parameter and return the config object. Inside the function, the config object will be modified in the following way: config.parameters. = , with being an attribute. - Example:: - - def config_builder(config): - import emodpy.emod_enum as emod_enum - config.parameters.Incubation_Period_Distribution = emod_enum.DistributionType.CONSTANT_DISTRIBUTION - config.parameters.Incubation_Period_Constant = 5 - config.parameters.Infectious_Period_Distribution = emod_enum.DistributionType.CONSTANT_DISTRIBUTION - config.parameters.Infectious_Period_Constant = 5 - config.parameters.Simulation_Duration = 80 - return config - - campaign_builder: Function that creates and adds interventions to the campaign module. The function needs + Example: + + ``` + def config_builder(config): + import emodpy.emod_enum as emod_enum + config.parameters.Incubation_Period_Distribution = emod_enum.DistributionType.CONSTANT_DISTRIBUTION + config.parameters.Incubation_Period_Constant = 5 + config.parameters.Infectious_Period_Distribution = emod_enum.DistributionType.CONSTANT_DISTRIBUTION + config.parameters.Infectious_Period_Constant = 5 + config.parameters.Simulation_Duration = 80 + return config + ``` + campaign_builder (Callable): Function that creates and adds interventions to the campaign module. The function needs to take the campaign module as the first required argument, which can then be followed by parameters that you want to modify within the interventions. These additional parameters are then available to be modified in a sweep. The function must return the campaign module at the end. - Example:: - - def campaign_builder(campaign, additional_param=0.3): - from emodpy.campaign.individual_intervention import CommonInterventionParameters, SimpleVaccine, VaccineType - from emodpy.campaign.distributor import add_intervention_scheduled - import emodpy.campaign.waning_config as waning_config - - this_waning_config = waning_config.BoxExponential(box_duration=25, - decay_time_constant=60, - initial_effect=0.89) - common_intervention_parameters = CommonInterventionParameters(cost=0.5, - dont_allow_duplicates=True) - vaccine = SimpleVaccine(campaign, - waning_config=this_waning_config, - vaccine_take=additional_param, - vaccine_type=VaccineType.TransmissionBlocking, - common_intervention_parameters=common_intervention_parameters) - add_intervention_scheduled(campaign, intervention_list=[vaccine], start_day=2) - return campaign - - - - demographics_builder: Function that builds the demographics configuration and optional migration + Example: + + ``` + def campaign_builder(campaign, additional_param=0.3): + from emodpy.campaign.individual_intervention import CommonInterventionParameters, SimpleVaccine, VaccineType + from emodpy.campaign.distributor import add_intervention_scheduled + import emodpy.campaign.waning_config as waning_config + + this_waning_config = waning_config.BoxExponential(box_duration=25, + decay_time_constant=60, + initial_effect=0.89) + common_intervention_parameters = CommonInterventionParameters(cost=0.5, + dont_allow_duplicates=True) + vaccine = SimpleVaccine(campaign, + waning_config=this_waning_config, + vaccine_take=additional_param, + vaccine_type=VaccineType.TransmissionBlocking, + common_intervention_parameters=common_intervention_parameters) + add_intervention_scheduled(campaign, intervention_list=[vaccine], start_day=2) + return campaign + ``` + demographics_builder (Callable): Function that builds the demographics configuration and optional migration configuration. - Example:: + Example: - def demographics_builder(): - import emodpy.demographics.Demographics as Demographics + ``` + def demographics_builder(): + import emodpy.demographics.Demographics as Demographics - demographics_object = Demographics.from_template_node(pop=500) - # other code setting demographics parameters - return demographics_object - - report_builder: Function that creates reports to be used in the experiment. The function must have Reporters + demographics_object = Demographics.from_template_node(pop=500) + # other code setting demographics parameters + return demographics_object + ``` + report_builder (Callable[[Reporters], Reporters]): Function that creates reports to be used in the experiment. The function must have Reporters object as the parameter and return that object. It is assumed that all the reporters come from the reporters that are part of EMOD main code. EMOD also supports reporters as custom plug-in dlls, however, not through the current emodpy system. - Example:: - - def report_builder(reporters): - from emodpy.reporters.reporters import ReportEventCounter, ReportFilter + Example: - report_filter = ReportFilter(start_day=0, end_day=365, filename_suffix="LifeEvents") - reporters.add(ReportEventCounter(reporters_object=reporters, - report_filter=report_filter, - event_list=["DiseaseDeaths", "Births", "HappyBirthday"])) - return reporters + ``` + def report_builder(reporters): + from emodpy.reporters.reporters import ReportEventCounter, ReportFilter - - embedded_python_scripts_path: Path to folder with python scripts or a list of paths to specific python + report_filter = ReportFilter(start_day=0, end_day=365, filename_suffix="LifeEvents") + reporters.add(ReportEventCounter(reporters_object=reporters, + report_filter=report_filter, + event_list=["DiseaseDeaths", "Births", "HappyBirthday"])) + return reporters + ``` + embedded_python_scripts_path (Union[str, Path, List[Union[str, Path]]]): Path to folder with python scripts or a list of paths to specific python scripts. When path to folder, all python scripts in the folder will be added to the experiment. embedded_python_scripts_path may also be a list of such items, each added independently. Note: We no longer support passing in a function for this parameter. - serialized_population_files: Path to folder containing .dtk serialized population files or specific + serialized_population_files (Union[str, List[str]]): Path to folder containing .dtk serialized population files or specific .dtk file, including the filename. All .dtk files in the folder will be added and used in the experiment. - bootstrapped: Set to True if the campaign builder will build a campaign from scratch itself. False if it + bootstrapped (bool): Set to True if the campaign builder will build a campaign from scratch itself. False if it will accept an initialized campaign from this function instead and then modify it. Default False. Returns: - EMODTask + EMODTask (EMODTask): The created task. """ task = cls(eradication_path=eradication_path, schema_path=schema_path) # We do not regenerate the schema from the Eradication binary because we can't guarantee this code is running @@ -509,26 +502,25 @@ def from_files(cls, Load custom EMOD files when creating [EMODTask][]. Args: - eradication_path: Path to Eradication binary, including the filename. - config_path: Path to the configuration file, including the filename. - campaign_path: Path to the campaign file, including the filename. - demographics_paths: Path or a list of paths to the folder containing demographics files or path to a + eradication_path (str): Path to Eradication binary, including the filename. + config_path (str): Path to the configuration file, including the filename. + campaign_path (str): Path to the campaign file, including the filename. + demographics_paths (Union[str, list]): Path or a list of paths to the folder containing demographics files or path to a specific demographics file, including the filename. When path to folder, all .json files in the folder will be added to the experiment as demographics files. - custom_reports_path: Path to the custom reports file, including the filename. It is assumed that all the + custom_reports_path (str): Path to the custom reports file, including the filename. It is assumed that all the reporters in the file come from the reporters that are part of EMOD main code. EMOD also supports reporters as custom plug-in dlls, however, not through the current emodpy system. - embedded_python_scripts_path: Path to folder with python scripts or path to a specific python script, + embedded_python_scripts_path (Union[str, list[str]]): Path to folder with python scripts or path to a specific python script, including the filename. When path to folder, all python scripts in the folder will be added to the - experiment. - Note: We no longer support passing in a function for this parameter. - serialized_population_files: Path to folder containing .dtk serialized population files or specific + experiment. Note: We no longer support passing in a function for this parameter. + serialized_population_files (Union[str, list[str]]): Path to folder containing .dtk serialized population files or specific .dtk file, including the filename. All .dtk files in the folder will be added and used in the experiment. - asset_path: Path to migration and/or climate files. + asset_path (str): Path to migration and/or climate files. Returns: - An initialized experiment + EMODTask (EMODTask): An initialized experiment. """ # Create the experiment task = cls(eradication_path=eradication_path) @@ -570,8 +562,7 @@ def from_files(cls, def pre_creation(self, parent: Union[Simulation, IWorkflowItem], platform: 'IPlatform'): """ - Call before a task is executed. This ensures our configuration is properly done - + Call before a task is executed. This ensures our configuration is properly done. """ # Set the demographics # self.demographics.set_task_config(self) @@ -612,9 +603,6 @@ def pre_creation(self, parent: Union[Simulation, IWorkflowItem], platform: 'IPla def set_command_line(self) -> None: """ Build and set the command line object. - - Returns: - """ # In COMPS, it's rare to have to specify multiple paths because 'we' control the environment and # can put everything in Assets. The multiple input paths is useful for local command-line usage where @@ -653,10 +641,7 @@ def set_command_line(self) -> None: def add_py_path(self, path_to_add) -> None: """ - Add path to list of python paths prepended to sys.path in embedded interpreter - - Returns: - + Add path to list of python paths prepended to sys.path in embedded interpreter. """ self.py_path_list.append(path_to_add) @@ -665,22 +650,16 @@ def set_sif(self, path_to_sif: Union[Path, str], platform: IPlatform) -> None: Set the singularity image file to use for creating the EMOD execution environment. Args: - path_to_sif: - - non-COMPSPlatforms: The file system path to the sif file for creating the EMOD execution environment. - COMPSPlatform: Either: + path_to_sif (Union[Path, str]): + - non-COMPSPlatforms: The file system path to the sif file for creating the EMOD execution environment. + - COMPSPlatform: Either: a) The same sif file path as with other platforms - b) A .id file containing a COMPS AssetCollection id containing the desired sif file, formatted e.g.:: - - 8df53802-53f3-ec11-a9f9-b88303911bc1::Asset Collection - - ContainerPlatform: No sif file specification is used. + b) A .id file containing a COMPS AssetCollection id containing the desired sif file, formatted e.g. '8df53802-53f3-ec11-a9f9-b88303911bc1::Asset Collection' - platform: Platform object to use for this task. + - ContainerPlatform: No sif file specification is used. - Returns: - None + platform (IPlatform): Platform object to use for this task. """ platform_type = platform.__class__.__name__ path_to_sif = Path(path_to_sif) @@ -719,9 +698,7 @@ def set_sif(self, path_to_sif: Union[Path, str], platform: IPlatform) -> None: def gather_common_assets(self) -> AssetCollection: """ - Gather Experiment Level Assets - Returns: - + Gather Experiment Level Assets. """ # check whether there are any .sif or .img files in the common assets diretories... # Add Eradication.exe to assets @@ -747,11 +724,9 @@ def gather_common_assets(self) -> AssetCollection: def _enforce_non_schema_coherence(self) -> None: """ This function enforces business logic that can't be encoded in the schema. + Rules: Start_Time + Simulation_Duration >= Minimum_End_Time - - Returns: - None """ if "Miminum_End_Time" in self.config: # only present when we enable Enable_Termination_On_Zero_Total_Infectivity if (self.config['Start_Time'] + self.config['Simulation_Duration']) < self.config['Minimum_End_Time']: @@ -761,9 +736,10 @@ def _enforce_non_schema_coherence(self) -> None: def gather_transient_assets(self) -> AssetCollection: """ - Gather assets that are per simulation + Gather assets that are per simulation. + Returns: - AssetCollection + AssetCollection (AssetCollection): The simulation assets. """ # This config code needs to be rewritten @@ -821,10 +797,10 @@ def copy_simulation(self, base_simulation: 'Simulation') -> 'Simulation': accidentally share objects between simulations. Args: - base_simulation: Base Simulation + base_simulation (Simulation): Base Simulation Returns: - New Simulation + Simulation (Simulation): The New Simulation """ simulation = copy.deepcopy(base_simulation) @@ -855,11 +831,11 @@ def set_parameter(self, name: str, value: any) -> dict: Set a value in the EMOD config.json file. This will be deprecated in the future in favour of emod_api.config. Args: - name: Name of parameter to set - value: Value to set + name (str): Name of parameter to set. + value (any): Value to set. Returns: - Tags to set + (dict): Tags to set. """ if not self.config: raise ValueError("task.config is empty. Please load a config file or dictionary" @@ -884,7 +860,7 @@ def set_parameter_sweep_callback(simulation: Simulation, param: str, value: Any) value: Value Returns: - Tags to set on simulation + (Dict[str, Any]): Tags to set on simulation. """ if not hasattr(simulation.task, 'set_parameter'): raise ValueError("set_parameter_sweep_callback can only be used on tasks with a set_parameter") @@ -893,13 +869,13 @@ def set_parameter_sweep_callback(simulation: Simulation, param: str, value: Any) @classmethod def set_parameter_partial(cls, parameter: str) -> partial[Simulation]: """ - Convenience callback for sweeps + Convenience callback for sweeps. Args: - parameter: Parameter to set + parameter (str): Parameter to set. Returns: - Partial function + (partial[Simulation]): Partial function. """ return partial(cls.set_parameter_sweep_callback, param=parameter) @@ -908,11 +884,11 @@ def get_parameter(self, name: str, default: Optional[Any] = None) -> Any: Get a parameter in the simulation. Args: - name: The name of the parameter. - default: Optional, the default value. + name (str): The name of the parameter. + default (Any): Optional, the default value. Returns: - The value of the parameter. + (Any): The value of the parameter. """ return self.config.get(name, default) @@ -953,13 +929,12 @@ def _add_files_from_path(path: str, valid_extension: str, process_file_callback: def add_embedded_python_scripts_from_path(self, path: Union[str, Path, List[Union[str, Path]]]) -> None: """ - Adds embedded python scripts from the path to the common assets + Adds embedded python scripts from the path to the common assets. Args: - path: Relative or absolute path to the file (including the file name) or to a folder containing - python scripts. Please note, all the python scripts in a specified folder will be added to the - simulation. path may also be a list of such items, each added independently. - + path (Union[str, Path, List[Union[str, Path]]]): Relative or absolute path to the file, including the file name, + or to a folder containing python scripts. Please note, all the python scripts in a specified folder will be added + to the simulation. path may also be a list of such items, each added independently. """ def process_valid_python_files(file_path: str): python_file_asset = Asset(file_path, relative_path="python") @@ -975,10 +950,10 @@ def process_valid_python_files(file_path: str): def add_serialized_population_files_from_path(self, path: str) -> None: """ - Adds serialized population files from the path to the common assets + Adds serialized population files from the path to the common assets. Args: - path: Relative or absolute path to the file (including the file name) or to the folder containing + path (str): Relative or absolute path to the file, including the file name, or to the folder containing the .dtk files. Please note, all the .dtk files in the folder will be added and be used in the simulations. """ @@ -1001,53 +976,55 @@ def reload_from_simulation(self, simulation: 'Simulation'): class EMODTaskSpecification(TaskSpecification): """ Idmtools implemented each platform and task as a Plugin and idmtools is able to identify them and use them - dynamically. For example, idmtools workflow is able to crete each Platform with Plaform Factory and each Task with + dynamically. For example, idmtools workflow is able to crete each Platform with Platform Factory and each Task with Task Factory. The link defined in setup.py entrypoint is the way to allow idmtools workflow to identify them. Take EMODTaskSpecification as an example, idmtools uses it internally and indirectly (user usually doesn't create an instance of it, but idmtools work may do in certain case). This EMODTaskSpecification entry in setup.py has been - used in idmtools workflow in two places: + used in idmtools workflow in two places. CLI command + - check idmtools related packages installed (version including plugins): idmtools version - check available Task: idmtools info plugins task """ def get(self, configuration: dict) -> EMODTask: """ - Return an EMODTask object using provided configuration + Return an EMODTask object using provided configuration. + Args: - configuration: Configuration for Task + configuration: Configuration for Task. Returns: - EMODTask for configuration + (EMODTask): EMODTask for configuration """ return EMODTask(**configuration) def get_description(self) -> str: """ - Defines a description of the plugin + Defines a description of the plugin. Returns: - Plugin description + (str): Plugin description """ return "Defines a EMODTask command" def get_type(self) -> Type[EMODTask]: """ - Returns the Task type defined by specification + Returns the Task type defined by specification. Returns: - + (Type[EMODTask]): Task type """ return EMODTask def get_version(self) -> str: """ - Return the version string for EMODTask. This should be the module version so return that + Return the version string for EMODTask. Returns: - Version + (str): Version """ from emodpy import __version__ return __version__ diff --git a/emodpy/generic/serialization.py b/emodpy/generic/serialization.py index 0c2a36d..1177b24 100644 --- a/emodpy/generic/serialization.py +++ b/emodpy/generic/serialization.py @@ -4,14 +4,11 @@ def enable_serialization(task: 'EMODTask', use_absolute_times: bool = False): """ - Enable serialization etierh by TIME or TIMESTEP based on use_absolute_times + Enable serialization either by TIME or TIMESTEP based on use_absolute_times. Args: - task: Task to enable - use_absolute_times: When true, *Serialization_Type* will be set to *TIME*, otherwise it will be set to - *TIMESTEP* - - Returns: - + task (EMODTask): Task to enable + use_absolute_times (bool): When true, **Serialization_Type** will be set to TIME, otherwise it will be set to + TIMESTEP. """ if use_absolute_times: task.set_parameter("Serialization_Type", "TIME") @@ -28,11 +25,10 @@ def add_serialization_timesteps(task: EMODTask, timesteps: List[int], end_at_fin Args: task (EMODTask): An EMODSimulation timesteps (List[int]): Array of integers representing the time steps to use - end_at_final (bool): False means set the simulation duration such that the last serialized_population file ends the simulation. NOTE- may not work if time step size is not 1 - use_absolute_times (bool): False means the method will define simulation times instead of time steps see documentation on Serialization_Type for details - - Returns: - + end_at_final (bool): False means set the simulation duration such that the last serialized_population + file ends the simulation. NOTE: may not work if time step size is not 1. + use_absolute_times (bool): False means the method will define simulation times instead of time steps + see documentation on Serialization_Type for details. """ enable_serialization(task, use_absolute_times) @@ -50,15 +46,12 @@ def add_serialization_timesteps(task: EMODTask, timesteps: List[int], end_at_fin def load_serialized_population(task: EMODTask, population_path: str, population_filenames: List[str]): - """Sets simulation to load a serialized population from the filesystem + """Sets simulation to load a serialized population from the filesystem. Args: task (EMODTask): An EMODSimulation population_path (str): relative path from the working directory to the location of the serialized population files. population_filenames (List[str]): names of files in question - - Returns: - """ task.update_parameters({"Serialized_Population_Path": population_path, "Serialized_Population_Filenames": population_filenames}) diff --git a/emodpy/reporters/base.py b/emodpy/reporters/base.py index bef95ee..17677ae 100644 --- a/emodpy/reporters/base.py +++ b/emodpy/reporters/base.py @@ -465,15 +465,19 @@ def json(self): def set_task_config(self, task: 'EMODTask') -> None: """ - Note: not using this method in the current implementation - because: task has Reporters object, but we have to give task to Reporters object so - that Reporters object can configure stuff in task. It makes more sense for Task to take Reporters object - and configure itself. + Configure reporter-related settings on the given EMODTask. - Configures reporter settings for config.json in the simulation + **NOTE** Historically this method allowed a Reporters object to modify a Task + (for example, to add reporter configuration into a simulation's + config.json). In the current design the Task is responsible for + applying Reporters' configuration itself, so this method is not used + by default. + + This method remains as an optional hook for callers that prefer the + Reporters object to push settings into a Task instance. Args: - task: Task to configure + task (EMODTask): Task to configure (optional; not used by default) """ pass diff --git a/emodpy/reporters/common.py b/emodpy/reporters/common.py index 297424c..4cf50f2 100644 --- a/emodpy/reporters/common.py +++ b/emodpy/reporters/common.py @@ -86,6 +86,8 @@ class ReportPluginAgeAtInfection(BuiltInReporter): """ Creates ReportPluginAgeAtInfection report to be added to the simulation. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/251) for the latest status. Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -101,6 +103,9 @@ class ReportPluginAgeAtInfectionHistogram(BuiltInReporter): """ Creates ReportPluginAgeAtInfectionHistogram report to be added to the simulation. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/49) for the latest status. + Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -137,6 +142,8 @@ class SqlReport(BuiltInReporter): the report output is a multi-table SQLite relational database (see https://sqlitebrowser.org/). Use the configuration parameters to manage the size of the database. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/219) for the latest status. Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -158,8 +165,8 @@ class SqlReport(BuiltInReporter): report_filter (ReportFilter, optional): Common report filtering parameters. Valid filtering parameters for this report are: - - start_day - - end_day + - start_day + - end_day """ @@ -223,14 +230,14 @@ class ReportEventCounter(BuiltInReporter): report_filter (ReportFilter, optional): Common report filtering parameters. Valid filtering parameters for this report are: - - start_day - - end_day - - filename_suffix - - node_ids - - min_age_years - - max_age_years - - must_have_ip_key_value - - must_have_intervention + - start_day + - end_day + - filename_suffix + - node_ids + - min_age_years + - max_age_years + - must_have_ip_key_value + - must_have_intervention """ def __init__(self, @@ -258,6 +265,8 @@ class ReportSimulationStats(BuiltInReporter): """ Creates the ReportSimulationStats to summarize key simulation statistics. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/220) for the latest status. Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -282,8 +291,8 @@ class ReportDrugStatus(BuiltInReporter): report_filter (ReportFilter, optional): Common report filtering parameters. Valid filtering parameters for this report are: - - start_day - - end_day + - start_day + - end_day """ def __init__(self, @@ -323,14 +332,17 @@ class ReportInfectionDuration(BuiltInReporter): The infection duration report (ReportInfectionDuration.csv)provides one line of information about an infection that has just cleared. It tells you who had the infection and how long they had it. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/249) for the latest status. + Args: reporters_object (Reporters): The reporters object given by the emodpy. report_filter (ReportFilter, optional): Common report filtering parameters. Valid filtering parameters for this report are: - - start_day - - end_day + - start_day + - end_day """ def __init__(self, @@ -397,13 +409,13 @@ class ReportEventRecorder(ConfigReporter): report_filter (ReportFilter, optional): Common report filtering parameters. Valid filtering parameters for this report are: - - start_day - - end_day - - node_ids - - min_age_years - - max_age_years - - must_have_ip_key_value - - must_have_intervention + - start_day + - end_day + - node_ids + - min_age_years + - max_age_years + - must_have_ip_key_value + - must_have_intervention """ @@ -451,6 +463,9 @@ class ReportNodeEventRecorder(ConfigReporter): status at the time of a node-level event. Additionally, it is possible to break up the population data by specific Node and Individual Properties. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/248) for the latest status. + Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -505,6 +520,9 @@ class ReportCoordinatorEventRecorder(ConfigReporter): The Coordinator-level events report (ReportCoordinatorEventRecorder.csv) records the event, time, and the coordinator sending out the event. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/247) for the latest status. + Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -536,6 +554,9 @@ class ReportSurveillanceEventRecorder(ConfigReporter): Node and Individual Properties. Only the nodes that the SurveillanceEventCoordinator listening to will be included in the report. + Additional documentation for this report is currently in development. + Check [here](https://github.com/EMOD-Hub/issues-and-discussions/issues/246) for the latest status. + Args: reporters_object (Reporters): The reporters object given by the emodpy. @@ -633,11 +654,12 @@ class SpatialReport(ConfigReporter): are defined in the SpatialReportChannels enum. Please use the enum to define the channels. - Example:: - - SpatialReport(reporters_object=reporters, - spatial_output_channels=[SpatialReportChannels.Infected, - SpatialReportChannels.Births]) + Example: + ``` + SpatialReport(reporters_object=reporters, + spatial_output_channels=[SpatialReportChannels.Infected, + SpatialReportChannels.Births]) + ``` """ diff --git a/emodpy/utils/collections_utils.py b/emodpy/utils/collections_utils.py index df92a0f..cc86143 100644 --- a/emodpy/utils/collections_utils.py +++ b/emodpy/utils/collections_utils.py @@ -5,15 +5,15 @@ def cut_iterable_to(obj: Iterable, to: int) -> Tuple[Union[List, Mapping], int]: """ - Cut an iterable to a certain length. + Cut an iterable to a certain length. Args: - obj: The iterable to cut. - to: The number of elements to return. + obj (Iterable): The iterable to cut. + to (int): The number of elements to return. Returns: - A list or dictionary (depending on the type of object) of elements and - the remaining elements in the original list or dictionary. + (Tuple[Union[List, Mapping], int]): A list or dictionary (depending on the type of object) of elements and + the remaining elements in the original list or dictionary. """ if isinstance(obj, dict): slice = {k: v for (k, v) in take(to, obj.items())} diff --git a/emodpy/utils/targeting_config.py b/emodpy/utils/targeting_config.py index 1517776..d1b2741 100644 --- a/emodpy/utils/targeting_config.py +++ b/emodpy/utils/targeting_config.py @@ -10,109 +10,111 @@ Below is the JSON for a simple example where we want to distribute a vaccine to 20% of the people that do not already have the vaccine on the 100th day of the simulation. - { - "class": "CampaignEvent", - "Start_Day": 100, - "Nodeset_Config": { - "class": "NodeSetAll" +``` +{ + "class": "CampaignEvent", + "Start_Day": 100, + "Nodeset_Config": { + "class": "NodeSetAll" + }, + "Event_Coordinator_Config": { + "class": "StandardInterventionDistributionEventCoordinator", + "Target_Demographic": "Everyone", + "Demographic_Coverage": 0.2, + "Targeting_Config": { + "class": "HasIntervention", + "Is_Equal_To": 0, + "Intervention_Name": "MyVaccine" }, - "Event_Coordinator_Config": { - "class": "StandardInterventionDistributionEventCoordinator", - "Target_Demographic": "Everyone", - "Demographic_Coverage": 0.2, - "Targeting_Config": { - "class": "HasIntervention", - "Is_Equal_To": 0, - "Intervention_Name": "MyVaccine" - }, - "Intervention_Config": { - "class": "SimpleVaccine", - "Intervention_Name" : "MyVaccine", - "Cost_To_Consumer": 1, - "Vaccine_Take": 1, - "Vaccine_Type": "AcquisitionBlocking", - "Waning_Config": { - "class": "WaningEffectConstant", - "Initial_Effect" : 1.0 - } + "Intervention_Config": { + "class": "SimpleVaccine", + "Intervention_Name" : "MyVaccine", + "Cost_To_Consumer": 1, + "Vaccine_Take": 1, + "Vaccine_Type": "AcquisitionBlocking", + "Waning_Config": { + "class": "WaningEffectConstant", + "Initial_Effect" : 1.0 } } } - +} +``` Below is a slightly more complicated example where we want to distribute a diagnostic to people that are either high risk or have not been vaccinated. - { - "class": "CampaignEvent", - "Start_Day": 100, - "Nodeset_Config": { - "class": "NodeSetAll" - }, - "Event_Coordinator_Config": { - "class": "StandardInterventionDistributionEventCoordinator", - "Target_Demographic": "Everyone", - "Demographic_Coverage": 0.2, - "Targeting_Config": { - "class" : "TargetingLogic", - "Logic" : [ - [ - { - "class": "HasIntervention", - "Is_Equal_To": 0, - "Intervention_Name": "MyVaccine" - } - ], - [ - { - "class": "HasIP", - "Is_Equal_To": 1, - "IP_Key_Value": "Risk:HIGH" - } - ] +``` +{ + "class": "CampaignEvent", + "Start_Day": 100, + "Nodeset_Config": { + "class": "NodeSetAll" + }, + "Event_Coordinator_Config": { + "class": "StandardInterventionDistributionEventCoordinator", + "Target_Demographic": "Everyone", + "Demographic_Coverage": 0.2, + "Targeting_Config": { + "class" : "TargetingLogic", + "Logic" : [ + [ + { + "class": "HasIntervention", + "Is_Equal_To": 0, + "Intervention_Name": "MyVaccine" + } + ], + [ + { + "class": "HasIP", + "Is_Equal_To": 1, + "IP_Key_Value": "Risk:HIGH" + } ] - }, - "Intervention_Config": { - "class": "SimpleDiagnostic", - "Treatment_Fraction": 1.0, - "Base_Sensitivity": 1.0, - "Base_Specificity": 1.0, - "Event_Or_Config": "Event", - "Positive_Diagnosis_Event": "TestedPositive" - } + ] + }, + "Intervention_Config": { + "class": "SimpleDiagnostic", + "Treatment_Fraction": 1.0, + "Base_Sensitivity": 1.0, + "Base_Specificity": 1.0, + "Event_Or_Config": "Event", + "Positive_Diagnosis_Event": "TestedPositive" } } - +} +``` The classes of emodpy are intended to make it easier for users to create complex logic and reduce the burden of trying to create this complex logic in JSON. Below is the python -configuration logic for the two examples above: +configuration logic for the two examples above. - # Example 1: Does not have MyVaccine - targeting_config = ~HasIntervention( intervention_name="MyVaccine" ) +- Example 1: Does not have MyVaccine
+`targeting_config = ~HasIntervention( intervention_name="MyVaccine" )` - # Example 2: Does not have MyVaccine OR is high risk - targeting_config = ~HasIntervention( intervention_name="MyVaccine" ) | HasIP( ip_key_value="Risk:HIGH" ) +- Example 2: Does not have MyVaccine OR is high risk
+`targeting_config = ~HasIntervention( intervention_name="MyVaccine" ) | HasIP( ip_key_value="Risk:HIGH" )` Notice that this logic uses the bitwise operators instead of the logical operators. Python does not allow you to override the logical operators so the bitwise operators -were the next best thing to allow simple notation. The bitwise operators are: +were the next best thing to allow simple notation. The bitwise operators are: -* '~' - use instead of "not" to logically invert the logical check -* '&' - use instead of "and" to logically AND two logical checks -* '|' - use instead of "or" to logically OR two logical checks -* '^' - XOR - NOT SUPPORTED -* '<<' - Left Shift - NOT SUPPORTED -* '>>' - Right Shift - NOT SUPPORTED +* ~ - use instead of "not" to logically invert the logical check +* & - use instead of "and" to logically AND two logical checks +* | - use instead of "or" to logically OR two logical checks +* ^ - XOR - NOT SUPPORTED +* Left Shift - NOT SUPPORTED +* Right Shift - NOT SUPPORTED The order of operations for bitwise operators is the same as for logical operators. For the operators we support, the following order of operations is followed: 1. Parentheses -2. '~' - NOT -3. '&' - AND -4. '|' - OR +2. ~ - NOT +3. & - AND +4. | - OR Please note that the bitwise operations should not change objects directly. You expect -them to return a new object with the operation. For example, if you have A_prime = ~A, +them to return a new object with the operation. For example, if you have A_prime = ~A, then you expect A_prime to be the inverse of A but you don't expect A to have changed. """ @@ -129,13 +131,14 @@ class AbstractTargetingConfig(ABC): classes must implement. This class is needed to tie the TargetingLogic and BaseTargetingConfig classes together. - class_name: The subclass is responsible for setting the name of the EMOD class. + - class_name: The subclass is responsible for setting the name of the EMOD class. This name does not need to be the same as the python class, but it must match what is used in EMOD. - is_equal_to: + - is_equal_to: This is a parameter in all of EMOD's Targeting_Config classes. The check performed by the class is compared with the value of this parameter. + For example, if using HasIP with ip_key_value = "Risk:HIGH" and is_equal_to = 0, individuals who do NOT have Risk = HIGH will be selected. If is_equal_to = 1, then individuals who DO have Risk = HIGH will be selected. @@ -223,8 +226,8 @@ def _clean_dict(self, read_only_dict): def to_simple_dict(self, campaign): """ - Return a plain/simple dictionary of the expected JSON for EMOD. The main - purpose of this is for validation in testing. We need the ability to see + Return a plain/simple dictionary of the expected JSON for EMOD. The main + purpose of this is for validation in testing. We need the ability to see that the logic written in python is translated to the JSON correctly. Args: @@ -247,15 +250,15 @@ class _TargetingLogic(AbstractTargetingConfig): TargetingLogic allows the user to logically combine different checks. We leverage bitwise operators to make the syntax of combining different checks low and straight forward. - NOTE: We put the initial and'ing and or'ing in the constructor to reduce the amount of + NOTE We put the initial and'ing and or'ing in the constructor to reduce the amount of object creation and to stop a situation where we would end up with a nested TargetingLogic - element that only had one element. See the "deeply nested" test in test_targeting_config.py. + element that only had one element. See the "deeply nested" test in test_targeting_config.py. Args: - is_and: If true, initialize the TargetingLogic object such that 'left' and 'right' are AND'd + is_and (bool): If true, initialize the TargetingLogic object such that 'left' and 'right' are AND'd together. If false, initialize it such that they are OR'd. - left: The targeting config object on the left side of the operator - right: The targeting config object on the right side of the operator + left (AbstractTargetingConfig): The targeting config object on the left side of the operator + right (AbstractTargetingConfig): The targeting config object on the right side of the operator """ def __init__(self, is_and: bool, left: AbstractTargetingConfig, right: AbstractTargetingConfig): super().__init__() @@ -344,7 +347,7 @@ def __or__(self, right): def pre_and(self, left): """ - Return a new object that is "and'd" with the object to the left of the '&' operator + Return a new object that is "and'd" with the object to the left of the '&' operator. """ copy_obj = copy.deepcopy(self) for inner in copy_obj.logic: @@ -353,7 +356,7 @@ def pre_and(self, left): def pre_or(self, left): """ - Return a new object that is "or'd" with the object to the left of the '|' operator + Return a new object that is "or'd" with the object to the left of the '|' operator. """ copy_obj = copy.deepcopy(self) inner = [] @@ -367,10 +370,10 @@ def to_schema_dict(self, campaign): This is the dictionary used to generate the JSON for EMOD. Args: - campaign: The campaign module that has the path to the schema + campaign (emodpy.campaign.emod_campaign.EMODCampaign): The campaign module that has the path to the schema Returns: - A ReadOnlyDict object created by schema_to_class + (ReadOnlyDict): A ReadOnlyDict object created by schema_to_class """ tc_out = super().to_schema_dict(campaign) tc_out.Logic = [] @@ -399,15 +402,15 @@ def _convert_logic_to_dict(self, tc_dict): def to_simple_dict(self, campaign): """ - Return a plain/simple dictionary of the expected JSON for EMOD. The main - purpose of this is for validation in testing. We need the ability to see + Return a plain/simple dictionary of the expected JSON for EMOD. The main + purpose of this is for validation in testing. We need the ability to see that the logic written in python is translated to the JSON correctly. Args: - campaign: The campaign module that has the path to the schema + campaign (emodpy.campaign.emod_campaign.EMODCampaign): The campaign module that has the path to the schema Returns: - A simple dictionary containing the data for EMOD. + (dict): A simple dictionary containing the data for EMOD. """ tc_obj = self.to_schema_dict(campaign) tc_dict = self._clean_dict(tc_obj) @@ -418,10 +421,10 @@ def to_simple_dict(self, campaign): class BaseTargetingConfig(AbstractTargetingConfig): """ The BaseTargetingConfig class should used as the base class for all of the - Targeting_Config classes. The main job of the subclasses is to maintain - the extra data needed by the class in EMOD to perform the check. For example, + Targeting_Config classes. The main job of the subclasses is to maintain + the extra data needed by the class in EMOD to perform the check. For example, HasIP needs to know the IP key:value so that in EMOD the class can check if - the individual has the given IP. HasIP is responsible for making sure it + the individual has the given IP. HasIP is responsible for making sure it is translated in the EMOD configuration. """ def __init__(self): @@ -471,8 +474,9 @@ class HasIP(BaseTargetingConfig): This is especially needed when determining if a partner has a particular IP (see emodpy-hiv.utils.targeting_config.HasRelationship). - ip_key_value: An IndividualProperties Key:Value pair where the key/property name and one of its - values is separated by a colon (':'). This cannot be an empty string. + Args: + ip_key_value (str): An IndividualProperties Key:Value pair where the key/property name and one of its + values is separated by a colon (':'). This cannot be an empty string. """ def __init__(self, ip_key_value): super().__init__() @@ -503,10 +507,11 @@ class HasIntervention(BaseTargetingConfig): This will only work for interventions that persist like SimpleVaccine and DelayedIntervention. It will not work for interventions like BroadcastEvent since it does not persist. - intervention_name: The name of the intervention the person should have. This cannot be an empty - string but should be either the name of the intervention class or the name given to the - intervention of interest. EMOD does not verify that this name exists or is used in your - campaign. + Args: + intervention_name (str): The name of the intervention the person should have. This cannot be an empty + string but should be either the name of the intervention class or the name given to the + intervention of interest. EMOD does not verify that this name exists or is used in your + campaign. """ def __init__(self, intervention_name): super().__init__()