Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ out/sim-*/plots
out/sim-*/dataset-*.hdf5
lib
venv
*~
*~
out/*/.DS_Store
.DS_Store
6 changes: 3 additions & 3 deletions config/simulation-charmeleon-alt.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
"seed": 42,
"remaster_xml": "src/remaster-template.xml",
"num_simulations": 2000,
"num_workers": 16,
"num_workers": 5,
"simulation_hyperparameters": {
"duration_range": {
"dist": "uniform_int",
"lower_bound": 30,
"upper_bound": 50
"lower_bound": 10,
"upper_bound": 30
},
"num_changes": {
"dist": "uniform_int",
Expand Down
37 changes: 37 additions & 0 deletions config/simulation-wartortle.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"simulation_name": "sim-wartortle",
"output_hdf5": "dataset-wartortle.hdf5",
"seed": 42,
"remaster_xml": "src/remaster-template-contemporaneous-lenient.xml",
"num_simulations": 2000,
"num_workers": 5,
"simulation_hyperparameters": {
"duration_range": {
"dist": "uniform_int",
"lower_bound": 10,
"upper_bound": 30
},
"num_changes": {
"dist": "uniform_int",
"lower_bound": 1,
"upper_bound": 2
},
"r0": {
"dist": "lognormal",
"LN_mean": 1.17,
"LN_sigma": 0.38
},
"net_removal_rate": {
"dist": "lognormal",
"LN_mean": -1.81,
"LN_sigma": 0.2
},
"sampling_prop": {
"dist": "beta",
"alpha": 2,
"beta": 10
},
"num_temp_measurements": 10,
"contemporaneous_sample": true
}
}
5 changes: 5 additions & 0 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,11 @@ def create_database(pickle_files):
"present_cumulative",
data=sim["simulation_results"]["present_cumulative"],
)

#put rho in database if doing contemporaneous sampling
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment style is inconsistent with the rest of the codebase. Other comments in this file have a space after the hash character. This comment should follow the same convention.

Suggested change
#put rho in database if doing contemporaneous sampling
# put rho in database if doing contemporaneous sampling

Copilot uses AI. Check for mistakes.
if "rho" in sim["parameters"].keys():
params_grp.create_dataset("rho", data=sim["parameters"]["rho"]["values"])
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rho parameter is stored differently from other parameters. Other parameters (r0, net_removal_rate, sampling_prop, etc.) are stored as subgroups with 'values' and 'change_times' datasets (see lines 630-637), but rho is stored as a direct dataset. For consistency with the existing data structure and to match how rho is accessed in get_output_distributions.py (line 29 which expects 'rho/values'), this should create a subgroup and store both values and change_times, even if change_times is None.

Suggested change
params_grp.create_dataset("rho", data=sim["parameters"]["rho"]["values"])
rho_grp = params_grp.create_group("rho")
rho_grp.create_dataset("values", data=sim["parameters"]["rho"]["values"])
rho_change_times = sim["parameters"]["rho"].get("change_times")
if rho_change_times is None:
# Store an empty dataset to maintain consistent structure
rho_grp.create_dataset("change_times", data=np.array([]))
else:
rho_grp.create_dataset("change_times", data=rho_change_times)

Copilot uses AI. Check for mistakes.

Comment on lines +646 to +650
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code block is incorrectly placed outside the 'with open(pf, "rb") as f:' context manager block (which ends at line 645). The variable 'sim' is defined inside that context, and 'params_grp' is created from data read inside that context. This code should be moved inside the with block before line 646, at the same indentation level as the other dataset creation code (lines 638-645).

Suggested change
#put rho in database if doing contemporaneous sampling
if "rho" in sim["parameters"].keys():
params_grp.create_dataset("rho", data=sim["parameters"]["rho"]["values"])
# put rho in database if doing contemporaneous sampling
if "rho" in sim["parameters"]:
params_grp.create_dataset(
"rho", data=sim["parameters"]["rho"]["values"]
)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thomaswilliams23 the other comment about how the rho is stored appears incorrect but I think copilot is correct on this one about the level of indentation. The sim value may not have the expected value outside of the context.

db_conn.attrs["num_simulations"] = num_sims
db_conn.attrs["creation_date"] = datetime.datetime.now().isoformat()
db_conn.close()
Expand Down
125 changes: 125 additions & 0 deletions src/get_output_distributions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import h5py
import numpy as np

#look at an hdf5 file, pull out present prevalence and cumulative incidence
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.



DB_FNAME = "out/sim-wartortle/dataset-wartortle.hdf5"
#DB_FNAME = "out/sim-charmeleon-alt/dataset-charmeleon-alt.hdf5"
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.

print(f"\nReading from {DB_FNAME}\n")


#read in
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
db_conn = h5py.File(DB_FNAME, "r")

epidemic_durations = np.array([db_conn[f"{key}/output/parameters/epidemic_duration"][()] for key in db_conn.keys()])

r0_values = [db_conn[f"{key}/output/parameters/r0/values"][()] for key in db_conn.keys()]
r0_ct = [db_conn[f"{key}/output/parameters/r0/change_times"][()] for key in db_conn.keys()]

net_removal_rates = [db_conn[f"{key}/output/parameters/net_removal_rate/values"][()] for key in db_conn.keys()]
net_removal_ct = [db_conn[f"{key}/output/parameters/net_removal_rate/change_times"][()] for key in db_conn.keys()]

sampling_prop_values = [db_conn[f"{key}/output/parameters/sampling_prop/values"][()] for key in db_conn.keys()]
sampling_prop_ct = [db_conn[f"{key}/output/parameters/sampling_prop/change_times"][()] for key in db_conn.keys()]

if "rho" in db_conn[f"record_000001/output/parameters/"].keys():
rho_values = np.array([db_conn[f"{key}/output/parameters/rho/values"][()] for key in db_conn.keys()])

num_param_changes = np.array([len(r0_ct[ix]) for ix in range(len(r0_ct))])
all_change_times = np.concatenate(r0_ct)

present_prevalence = np.array([db_conn[f"{key}/output/present_prevalence"][()] for key in db_conn.keys()])
present_cumulative = np.array([db_conn[f"{key}/output/present_cumulative"][()] for key in db_conn.keys()])





#process parameter samples
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
all_r0_samples = np.concatenate(r0_values)
r0_weights = np.concatenate([
np.diff(np.concatenate((np.array([0.0]), change_times, np.array([epidemic_durations[ix]])))) for (ix, change_times) in enumerate(r0_ct)
])

all_net_removal_samples = np.concatenate(net_removal_rates)
net_removal_weights = np.concatenate([
np.diff(np.concatenate((np.array([0.0]), change_times, np.array([epidemic_durations[ix]])))) for (ix, change_times) in enumerate(net_removal_ct)
])

all_sampling_prop_samples = np.concatenate(sampling_prop_values)
sampling_prop_weights = np.concatenate([
np.diff(np.concatenate((np.array([0.0]), change_times, np.array([epidemic_durations[ix]])))) for (ix, change_times) in enumerate(sampling_prop_ct)
])








# MODEL PARAMS
print("\nModel Parameter Distributions:")

#r0
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
r0_median = np.median(all_r0_samples)
r0_interval = np.percentile(all_r0_samples, [2.5, 97.5], weights=r0_weights, method='inverted_cdf')
print(f"R0: Median={r0_median:.4f}, 95% interval=({r0_interval[0]:.4f}, {r0_interval[1]:.4f})")

#net removal rate
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
net_removal_median = np.median(all_net_removal_samples)
net_removal_interval = np.percentile(all_net_removal_samples, [2.5, 97.5], weights=net_removal_weights, method='inverted_cdf')
print(f"Net Removal Rate: Median={net_removal_median:.4f}, 95% interval=({net_removal_interval[0]:.4f}, {net_removal_interval[1]:.4f})")

#sampling proportion
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
sampling_prop_median = np.median(all_sampling_prop_samples)
sampling_prop_interval = np.percentile(all_sampling_prop_samples, [2.5, 97.5], weights=sampling_prop_weights, method='inverted_cdf')
print(f"Sampling Proportion: Median={sampling_prop_median:.4f}, 95% interval=({sampling_prop_interval[0]:.4f}, {sampling_prop_interval[1]:.4f})")

#rho if present
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
if "rho" in db_conn[f"record_000001/output/parameters/"].keys():
rho_median = np.median(rho_values)
rho_interval = np.percentile(rho_values, [2.5, 97.5])
print(f"Rho (Contemporaneous Sampling Proportion): Median={rho_median:.4f}, 95% interval=({rho_interval[0]:.4f}, {rho_interval[1]:.4f})")




#HYPERPARAMS
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
print("\nHyperparameter Distributions:")

#epidemic duration
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
epidemic_duration_median = np.median(epidemic_durations)
epidemic_duration_interval = np.percentile(epidemic_durations, [2.5, 97.5])
print(f"Epidemic Duration: Median={epidemic_duration_median:.4f}, 95% interval=({epidemic_duration_interval[0]:.4f}, {epidemic_duration_interval[1]:.4f})")

#number of parameter changes
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
num_param_changes_median = np.median(num_param_changes)
num_param_changes_interval = np.percentile(num_param_changes, [2.5, 97.5])
print(f"Number of Parameter Changes: Median={num_param_changes_median:.4f}, 95% interval=({num_param_changes_interval[0]:.4f}, {num_param_changes_interval[1]:.4f})")

#change times
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
all_change_times_median = np.median(all_change_times)
all_change_times_interval = np.percentile(all_change_times, [2.5, 97.5])
print(f"Change Times: Median={all_change_times_median:.4f}, 95% interval=({all_change_times_interval[0]:.4f}, {all_change_times_interval[1]:.4f})")




#OUTPUT
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
print("\nOutput Distributions:")

#prevalence
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
prevalence_median = np.median(present_prevalence)
prevalence_interval = np.percentile(present_prevalence, [2.5, 97.5])
print(f"Present Prevalence: Median={prevalence_median:.4f}, 95% interval=({prevalence_interval[0]:.4f}, {prevalence_interval[1]:.4f})")


#cumulative incidence
Copy link

Copilot AI Jan 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comments in Python should have a space after the hash character for readability. The comment style is inconsistent with standard Python conventions (PEP 8).

Copilot uses AI. Check for mistakes.
cumulative_median = np.median(present_cumulative)
cumulative_interval = np.percentile(present_cumulative, [2.5, 97.5])
print(f"Present Cumulative Incidence: Median={cumulative_median:.4f}, 95% interval=({cumulative_interval[0]:.4f}, {cumulative_interval[1]:.4f})")
print("\n")
32 changes: 32 additions & 0 deletions src/remaster-template-contemporaneous-lenient.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<beast version='2.0' namespace='beast.base.inference.parameter:beast.base.inference:remaster'>
<run spec="Simulator" nSims="1">

<simulate id="tree"
spec="SimulatedTree"
maxRetries="20">
<trajectory id="trajectory"
spec="StochasticTrajectory"
maxTime="50"
endsWhen="X==500000"
mustHave="Psi&lt;1001 &amp;&amp; Psi>1 &amp;&amp; X>1">

<population id="X" spec="RealParameter" value="1" />
<samplePopulation id="Psi" spec="RealParameter" value="0" />
<population id="Mu" spec="RealParameter" value="0" />

<reaction id="lambdaReaction" spec="Reaction" rate="0.2" >X -> 2X</reaction>
<reaction id="rhoReaction" spec="PunctualReaction" p="0.01" times="50">X -> Psi</reaction>
<reaction id="muReaction" spec="Reaction" rate="0.046">X -> Mu</reaction>

</trajectory>
</simulate>

<logger fileName="out/demo.tree" mode="tree">
<log spec="TypedTreeLogger" tree="@tree" />
</logger>

<logger fileName="out/demo.log">
<log idref="trajectory" />
</logger>
</run>
</beast>
2 changes: 1 addition & 1 deletion src/remaster-template-contemporaneous.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<population id="Mu" spec="RealParameter" value="0" />

<reaction id="lambdaReaction" spec="Reaction" rate="0.2" >X -> 2X</reaction>
<reaction id="rhoReaction" spec="PunctualReaction" p="0.01" times="50">X -> Psi</reaction>
<reaction id="rhoReaction" spec="PunctualReaction" p="0.01" times="50">X -> Psi</reaction>
<reaction id="muReaction" spec="Reaction" rate="0.046">X -> Mu</reaction>

</trajectory>
Expand Down