Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main'
Browse files Browse the repository at this point in the history
# Conflicts:
#	emodpy_typhoid/interventions/typhoid_vaccine.py
#	examples/future_campaign/multi_sweep.py
#	examples/future_campaign/requirements.txt
#	examples/vax_efficacy_sweep/requirements.txt
  • Loading branch information
AKraay-IDM committed Jan 8, 2024
2 parents 53616c5 + 5bd157f commit a0788fb
Show file tree
Hide file tree
Showing 47 changed files with 13,078 additions and 168 deletions.
2 changes: 1 addition & 1 deletion .bump_version.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
__version__ = '0.0.4'
__version__ = '0.1.0'
commit = True
tag = False

Expand Down
19 changes: 15 additions & 4 deletions .github/workflows/run_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ jobs:
- name: install test dependencies
run: |
pip3 install unittest-xml-reporting pytest
# - name: Install idm-test package
# run: |
# pip install idm-test>=0.0.13 --extra-index-url https://packages.idmod.org/api/pypi/pypi-production/simple
- name: Install idm-test package
run: |
pip install idm-test>=0.1.2 --extra-index-url https://packages.idmod.org/api/pypi/pypi-production/simple
- name: Login to comps2
run: |
python ./.dev_scripts/create_auth_token_args.py --username "${{ secrets.COMPS_USER }}" --password "${{ secrets.COMPS_PASSWORD }}"
Expand All @@ -56,6 +56,17 @@ jobs:
if: failure()
uses: actions/upload-artifact@v3
with:
name: unittest_results
name: workflow_results
path: |
**/test_results.xml
- name: run sft tests
run: |
cd tests/sft_tests
python run_all_sft_tests.py
- name: Upload workflow tests results to artifactory
if: failure()
uses: actions/upload-artifact@v3
with:
name: sft_results
path: |
**/test_results.xml
13 changes: 13 additions & 0 deletions Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,19 @@ podTemplate(
build_ok = false
echo e.toString()
}
try{
stage('SFT Test') {
echo "Running SFT Tests"
dir('tests/sft_tests') {
sh 'pip3 install idm-test>=0.1.2 --index-url=https://packages.idmod.org/api/pypi/pypi-production/simple'
sh 'python3 run_all_sft_tests.py'
junit '**/test_results.xml'
}
}
} catch(e) {
build_ok = false
echo e.toString()
}

// stage('Run Examples') {
// echo "Running examples"
Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@
search_project = os.environ["READTHEDOCS_PROJECT"]
search_version = os.environ["READTHEDOCS_VERSION"]

rtd_sphinx_search_default_filter = f"subprojects:{search_project_parent}/{search_version}"
rtd_sphinx_search_default_filter = f"subprojects:{search_project}/{search_version}"

rtd_sphinx_search_filters = {
"Search this project": f"project:{search_project}/{search_version}",
Expand Down
40 changes: 29 additions & 11 deletions emodpy_typhoid/interventions/typhoid_vaccine.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def new_intervention( camp, efficacy=0.82, mode="Shedding", constant_period=0, d
decay_constant (float, optional): The decay time constant for the waning effect. Default is 6935.0.
expected_expiration (float, optional): The mean duration before efficacy becomes 0. If this is set to non-zero value, the constant_period and decay_constant are ignored. These are two different modes of waning.
Returns:
TyphoidVaccine: A fully configured instance of the TyphoidVaccine intervention with the specified parameters.
"""
Expand All @@ -36,9 +35,10 @@ def new_intervention( camp, efficacy=0.82, mode="Shedding", constant_period=0, d
intervention.Mode = mode
intervention.Changing_Effect = _get_waning( constant_period=constant_period, decay_constant=decay_constant, expected_expiration=expected_expiration )
intervention.Changing_Effect.Initial_Effect = efficacy

return intervention

def new_vax( camp, efficacy=0.82, mode="Acquisition", constant_period=0, decay_constant=0, expected_expiration=0 ):
def new_vax( camp, efficacy=0.82, mode="Acquisition", constant_period=0, decay_constant=0, expected_expiration=0, deduplication_policy="replace" ):
"""
Create a new 'SimpleVaccine' intervention with specified parameters. If you use this function directly, you'll need to distribute the intervention with a function like ScheduledCampaignEvent or TriggeredCampaignEvent from emod_api.interventions.common.
Expand All @@ -49,6 +49,7 @@ def new_vax( camp, efficacy=0.82, mode="Acquisition", constant_period=0, decay_c
constant_period (float, optional): The constant period of the waning effect in days. Default is 0.
decay_constant (float, optional): The decay time constant for the waning effect. Default is 6935.0.
expected_expiration (float, optional): The mean duration before efficacy becomes 0. If this is set to non-zero value, the constant_period and decay_constant are ignored. These are two different modes of waning.
deduplication_policy (string): "replace" (default) or "combine". If giving vax to someone who already has one, based on Intervention_Name which defaults to intervention classname ("SimpleVaccine"), "replace" will purge the existing one, and "combine" will add the new one without replacement, and rely on code and configuration to calculate the combinatorix. If using "combine", make sure you _know_ the combinatorix.
Returns:
SimpleVaccine: A fully configured instance of the SimpleVaccine intervention with the specified parameters.
Expand All @@ -64,6 +65,16 @@ def new_vax( camp, efficacy=0.82, mode="Acquisition", constant_period=0, decay_c
else:
raise ValueError( f"mode {mode} not recognized. Options are: 'Acquisition', 'Transmission', or 'All'." )

# combine: DAD=0
# replace: DAD=1, EIR=1
# abort: DAD=1, EIR=0 -- not supported
if deduplication_policy == "replace":
intervention.Enable_Intervention_Replacement = 1 # D_A_D should be set implicitly
elif deduplication_policy == "combine":
intervention.Dont_Allow_Duplicates = 0
else:
raise ValueError( f"deduplication_policy needs to be 'replace' or 'combine', not '{deduplication_policy}'." )

intervention.Waning_Config = _get_waning( constant_period=constant_period, decay_constant=decay_constant, expected_expiration=expected_expiration )
intervention.Waning_Config.Initial_Effect = efficacy
return intervention
Expand Down Expand Up @@ -95,14 +106,18 @@ def new_triggered_intervention(
coverage (float, optional): Demographic coverage of the intervention. Default is 1.0.
node_ids (list, optional): List of node IDs where the intervention is applied. Default is None.
property_restrictions_list (list, optional): List of property restrictions for the intervention. Default is an empty list.
co_event (None, optional): Expansion slot for future use.
co_event (None, optional): The name of the event to be broadcast. This event name can be set in the Report_Event_Recorder_Events configuration parameter. It will be collected in ReportEventRecorder.csv with default event "VaccineDistributed".
Returns:
TriggeredCampaignEvent: An instance of a triggered campaign event with the TyphoidVaccine intervention.
"""
iv = new_intervention( camp, efficacy=efficacy, mode=mode, constant_period=constant_period, decay_constant=decay_constant )

event = common.TriggeredCampaignEvent( camp, Start_Day=start_day, Triggers=triggers, Demographic_Coverage=coverage, Intervention_List=[ iv ], Node_Ids=node_ids, Property_Restrictions=property_restrictions_list, Event_Name="Triggered Typhoid Vax" )
if co_event:
signal = common.BroadcastEvent(camp, co_event)
iv = [iv, signal]
else:
iv = [iv]
event = common.TriggeredCampaignEvent( camp, Start_Day=start_day, Triggers=triggers, Demographic_Coverage=coverage, Intervention_List=iv, Node_Ids=node_ids, Property_Restrictions=property_restrictions_list, Event_Name="Triggered Typhoid Vax" )

return event

Expand Down Expand Up @@ -135,11 +150,12 @@ def new_routine_immunization(
coverage (float, optional): Demographic coverage of the intervention. Default is 1.0.
node_ids (list, optional): List of node IDs where the intervention is applied. Default is None.
property_restrictions_list (list, optional): List of property restrictions for the intervention. Default is an empty list.
co_event (None, optional): Expansion slot for future use.
co_event (str, optional): The name of the event to be broadcast. This event name can be set in the Report_Event_Recorder_Events configuration parameter. It will be collected in ReportEventRecorder.csv with default event "VaccineDistributed" if not set with other name.
Returns:
TriggeredCampaignEvent: An instance of a triggered campaign event with the TyphoidVaccine intervention.
"""
# routine_immunization will always be a first vax (unless something is really whack) so mode doesn't matter.
iv = new_vax( camp, efficacy=efficacy, mode=mode, constant_period=constant_period, decay_constant=decay_constant, expected_expiration=expected_expiration )
if co_event:
signal = common.BroadcastEvent( camp, co_event )
Expand Down Expand Up @@ -185,17 +201,19 @@ def new_scheduled_intervention(
coverage (float, optional): Demographic coverage of the intervention. Default is 1.0.
node_ids (list, optional): List of node IDs where the intervention is applied. Default is None.
property_restrictions_list (list, optional): List of property restrictions for the intervention. Default is an empty list.
co_event (None, optional): Expansion slot for future use.
co_event (None, optional): The name of the event to be broadcast. This event name can be set in the Report_Event_Recorder_Events configuration parameter. It will be collected in ReportEventRecorder.csv if set not None or "".
Returns:
ScheduledCampaignEvent: An instance of a scheduled campaign event with the TyphoidVaccine intervention.
"""
iv = new_intervention( camp, efficacy=efficacy, mode=mode, constant_period=constant_period, decay_constant=decay_constant )

#event = common.ScheduledCampaignEvent( camp, Start_Day=start_day, Demographic_Coverage=coverage, Intervention_List=[ act_intervention, bcast_intervention ], Node_Ids=nodeIDs, Property_Restrictions=property_restrictions_list )
event = common.ScheduledCampaignEvent( camp, Start_Day=start_day, Demographic_Coverage=coverage, Intervention_List=[ iv ], Node_Ids=node_ids, Property_Restrictions=property_restrictions_list )

if co_event:
signal = common.BroadcastEvent(camp, co_event)
iv = [iv, signal]
else:
iv = [iv]
event = common.ScheduledCampaignEvent( camp, Start_Day=start_day, Demographic_Coverage=coverage, Intervention_List=iv, Node_Ids=node_ids, Property_Restrictions=property_restrictions_list )
return event

def new_intervention_as_file( camp, start_day, filename=None ):
Expand Down
2 changes: 1 addition & 1 deletion examples/HINTy/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
emodpy-typhoid==0.0.5.dev2
emodpy-typhoid==0.0.5
emodpy==1.22.0.dev3
emod-api==1.31.0.dev0
emod-typhoid==0.0.4.dev2
58 changes: 38 additions & 20 deletions examples/future_campaign/multi_sweep.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
from emodpy_typhoid.utility.sweeping import ItvFn, CfgFn, set_param, sweep_functions


BASE_YEAR = 2005
SIMULATION_DURATION_IN_YEARS = 25
BASE_YEAR = 1990
SIMULATION_DURATION_IN_YEARS = 40
CAMP_START_YEAR = 2015
FWD_CAMP_START_YEAR = 2024.25

Expand All @@ -40,14 +40,13 @@ def set_param_fn(config):
config.parameters.Inset_Chart_Reporting_Start_Year = BASE_YEAR
config.parameters.Inset_Chart_Reporting_Stop_Year = 2030
config.parameters.Enable_Demographics_Reporting = 0
#config.parameters.Enable_Property_Output = 1 # crash
#config.parameters.Report_Event_Recorder_Events = ["VaccineDistributed", "PropertyChange", "NewInfectionEvent" ]
config.parameters.Enable_Property_Output = 0
config.parameters.Report_Event_Recorder_Events = ["NewInfectionEvent" ]
config.parameters["Listed_Events"] = ["VaccineDistributed"] # old school

config.parameters.Report_Typhoid_ByAgeAndGender_Start_Year = 2010
config.parameters.Report_Typhoid_ByAgeAndGender_Stop_Year = 2030
config.parameters.Age_Initialization_Distribution_Type = "DISTRIBUTION_COMPLEX"
#config.parameters.Age_Initialization_Distribution_Type = "DISTRIBUTION_COMPLEX" # move to after
config.parameters.Typhoid_3year_Susceptible_Fraction = 0
config.parameters.Typhoid_6month_Susceptible_Fraction = 0
config.parameters.Typhoid_6year_Susceptible_Fraction = 0
Expand Down Expand Up @@ -95,14 +94,14 @@ def add_historical_vax( camp, ria_coverage=0.75, camp_coverage=0.75, efficacy=0.
ria = tv.new_routine_immunization(camp,
efficacy=efficacy,
constant_period=0,
expected_expiration=expiration,
#decay_constant=values['decay_constant'],
#expected_expiration=expiration,
decay_constant=expiration,
start_day=year_to_days(CAMP_START_YEAR),
coverage=ria_coverage)
tv_iv = tv.new_vax(camp,
efficacy=efficacy,
expected_expiration=expiration,
#decay_constant=values['decay_constant'],
#expected_expiration=expiration,
decay_constant=expiration,
constant_period=0)

notification_iv = comm.BroadcastEvent(camp, "VaccineDistributed")
Expand All @@ -114,7 +113,7 @@ def add_historical_vax( camp, ria_coverage=0.75, camp_coverage=0.75, efficacy=0.
Demographic_Coverage=camp_coverage,
Target_Age_Min=0.75,
Target_Age_Max=15
)
)
camp.add(one_time_campaign)

#add_historical_vax( camp )
Expand Down Expand Up @@ -151,7 +150,10 @@ def add_vax_intervention(campaign, values, min_age=0.75, max_age=15, binary_immu
import emodpy_typhoid.interventions.typhoid_vaccine as tv
print(f"Telling emod-api to use {manifest.schema_file} as schema.")
campaign.set_schema(manifest.schema_file)
camp_coverage = values['coverage_camp']
for key in values.keys():
if 'coverage' in key:
camp_coverage = values[key]
break

if binary_immunity:
tv_iv = tv.new_vax(campaign,
Expand All @@ -165,6 +167,12 @@ def add_vax_intervention(campaign, values, min_age=0.75, max_age=15, binary_immu
constant_period=0)

notification_iv = comm.BroadcastEvent(campaign, "VaccineDistributed")
# NOTE: the order of interventions in Intervention_List matters. This is because multiple
# interventions are delivered using a MultiInterventionDistributor intervention and de-duplication
# operates on Intervention_Name, so that when we try to distribute this intervention 'package',
# the model looks at the name of the existing intervention, which is the vax, and the name of the
# 'package' here, which would be MultiInterventionDistributor. But there is code in emod_api which
# sets the MID name to the name of the first intervention in the list, which here will be SimpleVaccine.
one_time_campaign = comm.ScheduledCampaignEvent(campaign,
Start_Day=year_to_days(FWD_CAMP_START_YEAR),
Intervention_List=[tv_iv, notification_iv],
Expand Down Expand Up @@ -219,6 +227,7 @@ def run( sweep_choice="All", age_targeted=True, binary_immunity=True ):
task.config.parameters.Demographics_Filenames = ["demographics.json","TestDemographics_pak_updated.json"]
task.config.parameters.Death_Rate_Dependence = "NONDISEASE_MORTALITY_BY_YEAR_AND_AGE_FOR_EACH_GENDER"
task.config.parameters.Birth_Rate_Dependence = "INDIVIDUAL_PREGNANCIES_BY_AGE_AND_YEAR"
task.config.parameters.Age_Initialization_Distribution_Type = "DISTRIBUTION_COMPLEX"
# this is dumb
task.common_assets.add_directory(assets_directory=manifest.assets_input_dir)
task.set_sif(manifest.sif)
Expand All @@ -234,7 +243,7 @@ def get_sweep_list_from_values(start_day_offset, vax_effs, cov, decay):
def get_sweep_list_full():
start_day_offset = [1]
vax_effs = np.linspace(0.1, 1.0, 10)
decay = [1, 365, 3650, 365000]
decay = [1, 365, 3650, 36500]
cov = np.linspace(start=0.0, stop=1.0, num=5)
return get_sweep_list_from_values(start_day_offset, vax_effs, cov, decay)

Expand Down Expand Up @@ -286,15 +295,26 @@ def get_sweep_list_duration():
sweep_list.append({'start_day_offset': c[0], 'efficacy': c[1], 'coverage': c[2], 'decay_constant': c[3]})
return sweep_list

def get_sweep_list_just_one():
start_day_offset = [1]
vax_effs = [1]
decay = [3000]
cov = [0.75]
combinations = list(itertools.product(start_day_offset, vax_effs, cov, decay))
sweep_list = []
for c in combinations:
sweep_list.append({'start_day_offset': c[0], 'efficacy': c[1], 'coverage_camp': c[2], 'decay_constant': c[3]})
return sweep_list

def get_sweep_list_from_csv():
# This is wrong. Just load rows. Code is recreating. But have to stop work for now.
import pandas as pd
df = pd.load_csv( manifest.sweep_config )
raise NotImplemented( "get_sweep_list_from_csv" )

def get_config_sweep_list():
tac = [ 13435, 15320 ]
tel = [ 5.0, 7.0 ]
tac = [ 13435 ]
tel = [ 7.0 ]
combinations = list(itertools.product(tac, tel))
sweep_list = []
for c in combinations:
Expand All @@ -307,7 +327,8 @@ def get_config_sweep_list():
"Coverage": get_sweep_list_coverage,
"Coverage_RIA": get_sweep_list_coverage_ria,
"Coverage_Camp": get_sweep_list_coverage_camp,
"Vax_Duration": get_sweep_list_duration
"Vax_Duration": get_sweep_list_duration,
"Just_One": get_sweep_list_just_one
}

if sweep_choice not in sweep_selections.keys():
Expand All @@ -319,10 +340,7 @@ def get_config_sweep_list():
else:
avi_age_coverage = partial( add_vax_intervention, min_age=0, max_age=125 )

if binary_immunity:
avi_decay = partial( avi_age_coverage, binary_immunity=True )
else:
avi_decay = partial( avi_age_coverage, binary_immunity=False )
avi_decay = partial( avi_age_coverage, binary_immunity=binary_immunity )

builders = get_sweep_builders(sweep_list, get_config_sweep_list(), add_vax_fn=avi_decay)

Expand All @@ -344,4 +362,4 @@ def get_config_sweep_list():
dtk.setup(manifest.model_dl_dir)

import sys
run( sys.argv[1] if len(sys.argv)>1 else "Efficacy" )
run( sys.argv[1] if len(sys.argv)>1 else "Just_One", binary_immunity=False )
Loading

0 comments on commit a0788fb

Please sign in to comment.