From 239e6bdadac754619259225cc8f0ea8edf0c8716 Mon Sep 17 00:00:00 2001 From: Kurt Frey Date: Mon, 20 Apr 2026 16:03:10 -0700 Subject: [PATCH 1/3] Working --- .../Assets/python/builder_demographics.py | 3 +- .../Assets/python/builder_reports.py | 4 +- .../Assets/python/dtk_post_process.py | 11 ++- model_measles03/Assets/python/global_data.py | 2 - .../experiment_none_ri70_nodes002/COMPS_ID.id | 1 + .../make01_param_dict.py | 5 +- .../make02_launch_sims.py | 0 .../make03_pool_brick.py | 0 .../experiment_none_ri70_nodes020/COMPS_ID.id | 1 + .../make01_param_dict.py | 97 +++++++++++++++++++ .../make02_launch_sims.py | 27 ++++++ .../make03_pool_brick.py | 19 ++++ .../make01_param_dict.py | 3 + .../figure_prevalence/make_fig_prevalence.py | 94 ++++++++++++++++++ 14 files changed, 260 insertions(+), 7 deletions(-) create mode 100644 model_measles03/experiment_none_ri70_nodes002/COMPS_ID.id rename model_measles03/{experiment_none_ri70 => experiment_none_ri70_nodes002}/make01_param_dict.py (95%) rename model_measles03/{experiment_none_ri70 => experiment_none_ri70_nodes002}/make02_launch_sims.py (100%) rename model_measles03/{experiment_none_ri70 => experiment_none_ri70_nodes002}/make03_pool_brick.py (100%) create mode 100644 model_measles03/experiment_none_ri70_nodes020/COMPS_ID.id create mode 100644 model_measles03/experiment_none_ri70_nodes020/make01_param_dict.py create mode 100644 model_measles03/experiment_none_ri70_nodes020/make02_launch_sims.py create mode 100644 model_measles03/experiment_none_ri70_nodes020/make03_pool_brick.py create mode 100644 model_measles03/figure_prevalence/make_fig_prevalence.py diff --git a/model_measles03/Assets/python/builder_demographics.py b/model_measles03/Assets/python/builder_demographics.py index 6dc233cf..1e06e8fa 100644 --- a/model_measles03/Assets/python/builder_demographics.py +++ b/model_measles03/Assets/python/builder_demographics.py @@ -27,6 +27,7 @@ def demographicsBuilder(): REF_CODE = gdata.var_params['ref_code'] REF_YEAR = gdata.var_params['ref_year'] NUM_NODES = gdata.var_params['num_nodes'] + INIT_POP = gdata.var_params['init_pop'] # Demographic reference data file dat_file = f'pop_dat_{REF_CODE}.csv' @@ -43,7 +44,7 @@ def demographicsBuilder(): node_id = 1 for k1 in range(NUM_NODES): - node_pop = float(gdata.init_pop) / NUM_NODES + node_pop = float(INIT_POP) / NUM_NODES imp_rate = R0/6.0 * node_pop * 1.615e-7 * np.power(10.0, LOG10_IMP) nname = 'EXAMPLE:A{:05d}'.format(node_id) node_obj = Node(lat=0.0, lon=0.0, pop=node_pop, diff --git a/model_measles03/Assets/python/builder_reports.py b/model_measles03/Assets/python/builder_reports.py index 6b0a90b3..7bc117ac 100644 --- a/model_measles03/Assets/python/builder_reports.py +++ b/model_measles03/Assets/python/builder_reports.py @@ -4,7 +4,7 @@ # # ***************************************************************************** -from emod_report_func import build_file, write_file +from emod_report_func import build_file, write_file, report_strain # ***************************************************************************** @@ -15,7 +15,7 @@ def reportsBuilder(): json_set = build_file() # Configurations - pass + report_strain(json_set, every_timestep=True) # Write file write_file(json_set) diff --git a/model_measles03/Assets/python/dtk_post_process.py b/model_measles03/Assets/python/dtk_post_process.py index 00885ad4..2aa9d941 100644 --- a/model_measles03/Assets/python/dtk_post_process.py +++ b/model_measles03/Assets/python/dtk_post_process.py @@ -3,6 +3,7 @@ # ***************************************************************************** import json +import os import sqlite3 import global_data as gdata @@ -11,7 +12,8 @@ from emod_postproc_func import post_proc_poppyr, post_proc_prev, post_proc_cost from emod_constants import SQL_TIME, SQL_MCW, SQL_AGE, O_FILE, MO_DAYS, \ - SQL_FILE, BASE_YEAR + SQL_FILE, BASE_YEAR, RST_FILE, RST_TIME, RST_NODE, \ + RST_TOT_INF # ***************************************************************************** @@ -32,6 +34,13 @@ def application(output_path): # Retain campaign cost output channel post_proc_cost(output_path, parsed_dat[key_str]) + # Post-process strain reporter + infdat = np.loadtxt(os.path.join(output_path, RST_FILE), + delimiter=',', skiprows=1, ndmin=2) + + infcol = infdat[:, [RST_TIME, RST_NODE, RST_TOT_INF]] + parsed_dat[key_str]['rst'] = infcol.tolist() + # Connect to SQL database; retreive new entries connection_obj = sqlite3.connect(SQL_FILE) cursor_obj = connection_obj.cursor() diff --git a/model_measles03/Assets/python/global_data.py b/model_measles03/Assets/python/global_data.py index b156cd79..ac77272e 100644 --- a/model_measles03/Assets/python/global_data.py +++ b/model_measles03/Assets/python/global_data.py @@ -18,8 +18,6 @@ demog_object = None # Other stuff -init_pop = 250000 - inf_prd_mean = 18.0 brate_mult_x = None diff --git a/model_measles03/experiment_none_ri70_nodes002/COMPS_ID.id b/model_measles03/experiment_none_ri70_nodes002/COMPS_ID.id new file mode 100644 index 00000000..6d0b2624 --- /dev/null +++ b/model_measles03/experiment_none_ri70_nodes002/COMPS_ID.id @@ -0,0 +1 @@ +38025497-0c3d-f111-92e2-000d3af5294c::Experiment \ No newline at end of file diff --git a/model_measles03/experiment_none_ri70/make01_param_dict.py b/model_measles03/experiment_none_ri70_nodes002/make01_param_dict.py similarity index 95% rename from model_measles03/experiment_none_ri70/make01_param_dict.py rename to model_measles03/experiment_none_ri70_nodes002/make01_param_dict.py index 1c115ea6..eea61d8a 100644 --- a/model_measles03/experiment_none_ri70/make01_param_dict.py +++ b/model_measles03/experiment_none_ri70_nodes002/make01_param_dict.py @@ -30,7 +30,7 @@ def write_param_dict(): # Setup param_dict = dict() - param_dict[EXP_NAME] = 'Measles03-NoSIAs-70RI' + param_dict[EXP_NAME] = 'Measles03-NoSIAs-70RI-Nodes002' param_dict[NUM_SIMS] = 250 param_dict[EXP_V] = dict() param_dict[EXP_C] = dict() @@ -57,6 +57,9 @@ def write_param_dict(): P_CON['ref_code'] = 'COD' P_CON['ref_year'] = 2040 + # Initial total population + P_CON['init_pop'] = 250000 + # Number of nodes P_CON['num_nodes'] = 2 diff --git a/model_measles03/experiment_none_ri70/make02_launch_sims.py b/model_measles03/experiment_none_ri70_nodes002/make02_launch_sims.py similarity index 100% rename from model_measles03/experiment_none_ri70/make02_launch_sims.py rename to model_measles03/experiment_none_ri70_nodes002/make02_launch_sims.py diff --git a/model_measles03/experiment_none_ri70/make03_pool_brick.py b/model_measles03/experiment_none_ri70_nodes002/make03_pool_brick.py similarity index 100% rename from model_measles03/experiment_none_ri70/make03_pool_brick.py rename to model_measles03/experiment_none_ri70_nodes002/make03_pool_brick.py diff --git a/model_measles03/experiment_none_ri70_nodes020/COMPS_ID.id b/model_measles03/experiment_none_ri70_nodes020/COMPS_ID.id new file mode 100644 index 00000000..9e74d607 --- /dev/null +++ b/model_measles03/experiment_none_ri70_nodes020/COMPS_ID.id @@ -0,0 +1 @@ +6ca2e29e-0c3d-f111-92e2-000d3af5294c::Experiment \ No newline at end of file diff --git a/model_measles03/experiment_none_ri70_nodes020/make01_param_dict.py b/model_measles03/experiment_none_ri70_nodes020/make01_param_dict.py new file mode 100644 index 00000000..a8a886f7 --- /dev/null +++ b/model_measles03/experiment_none_ri70_nodes020/make01_param_dict.py @@ -0,0 +1,97 @@ +# ***************************************************************************** +# +# ***************************************************************************** + +import json +import os +import sys + +import numpy as np + +# Ought to go in emodpy +sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'local_python'))) +from py_assets_common.emod_constants import EXP_C, EXP_V, EXP_NAME, NUM_SIMS, \ + P_FILE + +# ***************************************************************************** + +# This script makes a json dictionary that is used by the pre-processing script +# in EMOD. Variable names defined here will be available to use in creating +# the input files. + +# The pre-process script will open the json dict created by this method. For +# everything with the EXP_V key, that script will assume a list and get a value +# from that list based on the sim index. For everything with the EXP_C key, it +# will assume a single value and copy that value. + + +def write_param_dict(): + + # Setup + param_dict = dict() + + param_dict[EXP_NAME] = 'Measles03-NoSIAs-70RI-Nodes020' + param_dict[NUM_SIMS] = 250 + param_dict[EXP_V] = dict() + param_dict[EXP_C] = dict() + + # Random number consistency + np.random.seed(4) + + # Convenience naming + NSIMS = param_dict[NUM_SIMS] + P_VAR = param_dict[EXP_V] + P_CON = param_dict[EXP_C] + + # Run number (EMOD random seed) + P_VAR['run_number'] = list(range(NSIMS)) + + # Infectivity + vals = 10.0 + np.random.gamma(30.0, scale=0.133, size=NSIMS) + P_VAR['R0'] = (np.round(vals, 2)).tolist() + + # RI params + P_CON['MCV1'] = 0.70 + + # Reference country code and year for population pyramid + P_CON['ref_code'] = 'COD' + P_CON['ref_year'] = 2040 + + # Initial total population + P_CON['init_pop'] = 250000 + + # Number of nodes + P_CON['num_nodes'] = 20 + + # SIA parameters + P_CON['sia_start_year'] = 1000 + P_CON['sia_interval_yrs'] = 3 + P_CON['sia_coverage'] = 0.60 + P_CON['sia_min_age_yr'] = 0.75 + P_CON['sia_max_age_yr'] = 5.00 + + # Log10 of multiplier on exogeneous case importation + P_CON['log10_import_mult'] = 1.0 + + # RI params + P_CON['MCV1_age'] = 270.0 + P_CON['Age_Take'] = True + P_CON['MCV2'] = 0.0 + + # Maternal protection effectiveness + P_CON['mat_factor'] = 1.0 + + # Write parameter dictionary + with open(P_FILE, 'w') as fid01: + json.dump(param_dict, fid01) + + return None + +# ***************************************************************************** + + +if (__name__ == "__main__"): + + write_param_dict() + +# ***************************************************************************** diff --git a/model_measles03/experiment_none_ri70_nodes020/make02_launch_sims.py b/model_measles03/experiment_none_ri70_nodes020/make02_launch_sims.py new file mode 100644 index 00000000..b0021616 --- /dev/null +++ b/model_measles03/experiment_none_ri70_nodes020/make02_launch_sims.py @@ -0,0 +1,27 @@ +# ***************************************************************************** +# +# ***************************************************************************** + +import os +import sys + +# Ought to go in emodpy +sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'local_python'))) +from emod_exp import start_exp +from py_assets_common.emod_constants import P_FILE + +# ***************************************************************************** + +# Paths +PATH_EXP_DEF = os.path.abspath(P_FILE) +PATH_PYTHON = os.path.abspath(os.path.join('..', 'Assets', 'python')) +PATH_DATA = os.path.abspath(os.path.join('..', 'Assets', 'data')) + +# ***************************************************************************** + + +if (__name__ == "__main__"): + + start_exp(PATH_PYTHON, PATH_DATA, PATH_EXP_DEF, short_queue=True) + +# ****************************************************************************** diff --git a/model_measles03/experiment_none_ri70_nodes020/make03_pool_brick.py b/model_measles03/experiment_none_ri70_nodes020/make03_pool_brick.py new file mode 100644 index 00000000..e4d01ba2 --- /dev/null +++ b/model_measles03/experiment_none_ri70_nodes020/make03_pool_brick.py @@ -0,0 +1,19 @@ +# ***************************************************************************** +# +# ***************************************************************************** + +import os +import sys + +# Ought to go in emodpy +sys.path.insert(0, os.path.abspath(os.path.join('..', '..', 'local_python'))) +from emod_reduce import get_data_brick + +# ***************************************************************************** + + +if (__name__ == "__main__"): + + get_data_brick() + +# ***************************************************************************** diff --git a/model_measles03/experiment_sia3yr60cv_ri70/make01_param_dict.py b/model_measles03/experiment_sia3yr60cv_ri70/make01_param_dict.py index 1cb67ad7..c533b6bb 100644 --- a/model_measles03/experiment_sia3yr60cv_ri70/make01_param_dict.py +++ b/model_measles03/experiment_sia3yr60cv_ri70/make01_param_dict.py @@ -57,6 +57,9 @@ def write_param_dict(): P_CON['ref_code'] = 'COD' P_CON['ref_year'] = 2040 + # Initial total population + P_CON['init_pop'] = 250000 + # Number of nodes P_CON['num_nodes'] = 2 diff --git a/model_measles03/figure_prevalence/make_fig_prevalence.py b/model_measles03/figure_prevalence/make_fig_prevalence.py new file mode 100644 index 00000000..90803f1d --- /dev/null +++ b/model_measles03/figure_prevalence/make_fig_prevalence.py @@ -0,0 +1,94 @@ +# ***************************************************************************** + +import json +import os +import sys + +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.patches as patch + +# Ought to go in emodpy +sys.path.append(os.path.abspath(os.path.join('..', '..', 'local_python'))) +sys.path.append(os.path.abspath(os.path.join('..', 'Assets', 'python'))) + +from py_assets_common.emod_constants import NUM_SIMS, P_FILE, POP_PYR, \ + D_FILE, EXP_C +from global_data import run_years, t_step_days + +# ***************************************************************************** + +DIRNAMES = ['experiment_none_ri70_nodes002', + 'experiment_none_ri70_nodes020'] + +# ***************************************************************************** + + +def make_fig(): + + # Figures + fig01 = plt.figure(figsize=(8, 6)) + + # Figures - Sims - Prevalance + axs01 = fig01.add_subplot(1, 1, 1) + plt.sca(axs01) + + axs01.grid(visible=True, which='major', ls='-', lw=0.5, label='') + axs01.grid(visible=True, which='minor', ls=':', lw=0.1) + axs01.set_axisbelow(True) + + for dirname in DIRNAMES: + + # Sim outputs + tpath = os.path.join('..', dirname) + + with open(os.path.join(tpath, D_FILE)) as fid01: + data_brick = json.load(fid01) + + with open(os.path.join(tpath, P_FILE)) as fid01: + param_dict = json.load(fid01) + + NSIMS = int(param_dict[NUM_SIMS]) + NNODES = int(param_dict[EXP_C]["num_nodes"]) + tvec = np.arange(0, 365*run_years, t_step_days) + + inf_dat = np.zeros((NSIMS, NNODES, len(tvec))) + pyr_mat = np.zeros((NSIMS, int(run_years)+1, 20))-1 + + for skey in data_brick: + if (not skey.isdigit()): + continue + + sim_idx = int(skey) + + inf_col = np.array(data_brick[skey]['rst']) # (Time, Node, Infections) + for k1 in range(inf_col.shape[0]): + time_idx = int(inf_col[k1, 0]/t_step_days) + node_idx = int(inf_col[k1, 1] - 1) # Node indicies are 1-based + inf_dat[sim_idx, node_idx, time_idx] = inf_col[k1, 2] + pyr_mat[sim_idx, :, :] = np.array(data_brick[skey][POP_PYR]) + + fidx = (pyr_mat[:, 0, 0] >= 0) + + non_zero_dat = (inf_dat[fidx, :, :] > 0) + non_zero_avg = np.mean(non_zero_dat, axis=(0,1)) # Lump sims and nodes + non_zero_std = np.std(non_zero_dat, axis=(0,1)) # Lump sims and nodes + + axs01.plot(tvec/365.0, non_zero_avg, color='C0', linewidth=2) + axs01.set_ylabel('Non-zero prevalence (fraction)', fontsize=16) + axs01.set_xlabel('Year', fontsize=16) + + plt.tight_layout() + plt.savefig('fig_prevalence_01.png'.format(dirname)) + plt.close() + + return None + +# ***************************************************************************** + + +if (__name__ == "__main__"): + + make_fig() + +# ***************************************************************************** From 5c8da22e5b13be3338613cebeb9a6eb28831a33a Mon Sep 17 00:00:00 2001 From: Kurt Frey Date: Mon, 20 Apr 2026 17:36:51 -0700 Subject: [PATCH 2/3] Figure with legend --- model_measles03/figure_prevalence/make_fig_prevalence.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/model_measles03/figure_prevalence/make_fig_prevalence.py b/model_measles03/figure_prevalence/make_fig_prevalence.py index 90803f1d..0a76aa53 100644 --- a/model_measles03/figure_prevalence/make_fig_prevalence.py +++ b/model_measles03/figure_prevalence/make_fig_prevalence.py @@ -74,11 +74,13 @@ def make_fig(): non_zero_avg = np.mean(non_zero_dat, axis=(0,1)) # Lump sims and nodes non_zero_std = np.std(non_zero_dat, axis=(0,1)) # Lump sims and nodes - axs01.plot(tvec/365.0, non_zero_avg, color='C0', linewidth=2) + axs01.plot(tvec/365.0, non_zero_avg, linewidth=2, + label='Nodes {:d}'.format(NNODES)) axs01.set_ylabel('Non-zero prevalence (fraction)', fontsize=16) axs01.set_xlabel('Year', fontsize=16) plt.tight_layout() + plt.legend() plt.savefig('fig_prevalence_01.png'.format(dirname)) plt.close() From c4c29926ffe32611b7e405c8a00ad2f311c4f178 Mon Sep 17 00:00:00 2001 From: Kurt Frey Date: Mon, 20 Apr 2026 21:51:58 -0700 Subject: [PATCH 3/3] Working --- model_measles03/figure_prevalence/make_fig_prevalence.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/model_measles03/figure_prevalence/make_fig_prevalence.py b/model_measles03/figure_prevalence/make_fig_prevalence.py index 0a76aa53..1cd0be19 100644 --- a/model_measles03/figure_prevalence/make_fig_prevalence.py +++ b/model_measles03/figure_prevalence/make_fig_prevalence.py @@ -61,7 +61,7 @@ def make_fig(): sim_idx = int(skey) - inf_col = np.array(data_brick[skey]['rst']) # (Time, Node, Infections) + inf_col = np.array(data_brick[skey]['rst']) # (Time, Node, TotInf) for k1 in range(inf_col.shape[0]): time_idx = int(inf_col[k1, 0]/t_step_days) node_idx = int(inf_col[k1, 1] - 1) # Node indicies are 1-based @@ -72,7 +72,6 @@ def make_fig(): non_zero_dat = (inf_dat[fidx, :, :] > 0) non_zero_avg = np.mean(non_zero_dat, axis=(0,1)) # Lump sims and nodes - non_zero_std = np.std(non_zero_dat, axis=(0,1)) # Lump sims and nodes axs01.plot(tvec/365.0, non_zero_avg, linewidth=2, label='Nodes {:d}'.format(NNODES))