10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118 | def create_scenarios(exp, scen_df):
"""
Creates OpenMalaria simulation scenarios based on a dataframe containing scenario parameters.
This function generates multiple OpenMalaria scenario XML files by replacing placeholders in a template
XML with specific parameters from the experiment configuration and scenario dataframe. Each scenario is
customized based on the parameters from the dataframe, and the resulting XML files are saved to the job directory.
Args:
exp (Experiment): The experiment object containing configuration parameters such as OpenMalaria version,
population size, simulation years, entomology mode, and other parameters required for
generating the scenarios.
scen_df (pandas.DataFrame): A dataframe containing scenario parameters such as seed values, clinical malaria
data, and other model-specific inputs.
Returns:
None
"""
with open(os.path.join(exp.openmalaria_input_path, 'scaffolds', f"{exp.openmalaria_scaffold}.xml"), "r") as fp:
xml = fp.read()
exp.days_between_clinical_cases_5days = 5 # Aurelien communicated that as long as we use v46, we should have a days_between_clinical_cases of 25 days
# Replace placeholders in the XML template with fixed parameters
xml = xml.replace("@version@", f"{exp.openmalaria_version}")
xml = xml.replace("@pop_size@", f"{exp.openmalaria_pop_size}")
xml = xml.replace("@burnin_start_year@", f"{exp.sim_start_year_openmalaria}")
xml = xml.replace("@start_year@", f"{exp.start_year - 1}")
xml = xml.replace("@end_year@", f"{exp.end_year - 1}")
xml = xml.replace("@survey_step@", f"{exp.openmalaria_survey_step}")
xml = xml.replace("@entomology_mode@", f"{exp.entomology_mode}")
xml = xml.replace("@detectionLimit@", f"{exp.detectionLimit}")
xml = xml.replace('@importation_rate@', f"{exp.openmalaria_importation_rate}")
xml = xml.replace('@healthSystemMemory@', f"{str(int(exp.days_between_clinical_cases_5days))}")
# Load from snippets
# Age Groups to monitor
xmlageGroups = '\t\t<ageGroup lowerbound="0">'
for item in exp.agebins:
xmlageGroups += f'\n\t\t\t<group upperbound="{item}"/>'
xml = xml.replace('<@age_groups@>', xmlageGroups)
# Age demography
snippet_file = 'age_demography.txt'
with open(os.path.join(exp.openmalaria_input_path, 'snippets', snippet_file), 'r', encoding='utf-8') as file:
snippet = file.read()
xml = xml.replace('@age_demography@', snippet)
# Interventions
if "cc_step" in exp.intervention_list:
xml = carrying_capacity(exp, xml)
else:
xml = xml.replace('@intervention_ccstep@', '')
# Model options
snippet_file = exp.openmalaria_modeloptions
with open(os.path.join(exp.openmalaria_input_path, 'snippets', snippet_file), 'r', encoding='utf-8') as file:
snippet = file.read()
xml = xml.replace('@model_options@', snippet)
# Model core parameters
snippet_file = exp.openmalaria_parameter
with open(os.path.join(exp.openmalaria_input_path, 'snippets', snippet_file), 'r', encoding='utf-8') as file:
snippet = file.read()
xml = xml.replace('@model_parameters@', snippet)
# Scenario sweeps and runs
df = rep_scen_df(scen_df)
for r, row in df.iterrows():
if row['cm_clinical'] == 0.45:
cm_clinical_5daily = 0.209261
elif row['cm_clinical'] == 0.15:
cm_clinical_5daily = 0.05161556
elif row['cm_clinical'] == 0:
cm_clinical_5daily = 0
else:
cm_clinical_5daily = convert_access_lookup(row['cm_clinical']) # converted from R function to python, returns an error if value outside of lookup range
# cm_clinical_5daily = convert_access(row['cm_clinical']) # TODO convert from R function to python
scenario = xml.replace('@seed@', str(row['seed']))
scenario = scenario.replace('@cm_clinical@', str(cm_clinical_5daily))
scenario = scenario.replace('@cm_severe@', str(row['cm_severe']))
scenario = scenario.replace('@eir@', str(row['transmission_intensity_OpenMalaria']))
if 'cc_step' in exp.intervention_list:
scenario = scenario.replace('@EIR_reduction@', str(row['cc_factor_OpenMalaria']))
scenario = scenario.replace('@step_change_time@', str(row['cc_timestep_OpenMalaria']))
#SMC currently not supported
#if 'smc' in exp.intervention_list:
# scenario = write_smc_deployment(scenario, row)
seasonality = getattr(exp, row['seasonality'])
# Replace seasonality placeholders with corresponding values from the experiment object
for i in range(1, 13):
scenario = scenario.replace(f'@seasonality{i}@', str(seasonality[i - 1]))
# Write the scenario XML file
with open(f"{exp.job_directory}/xml/{row['index']}.xml", 'w') as fo:
fo.write(f"{scenario}")
# Copy additional files required by OpenMalaria
shutil.copy(exp.openmalaria_path + "/densities.csv", f"{exp.job_directory}/")
schema = f"scenario_{exp.openmalaria_version}.xsd"
shutil.copy(os.path.join(exp.openmalaria_path, schema), exp.job_directory)
|