Skip to content

Making a Restart Point

Samuel Jenness edited this page Oct 17, 2026 · 2 revisions

Who this is for: anyone who calibrates a model or changes model code after calibration. Before you start: Calibrating a Model and Running Project Workflows on the HPC.

What a restart point is

Our models need a long burn-in before their populations and epidemics look realistic: the Template runs 70 years (calibration_end) from a population built from the network estimates. A restart point is the saved end state of one such simulation. Later runs start from it instead of repeating the burn-in: calibration fine-tuning, module debugging in chapter B after calibration, and every intervention run in chapter D. It lives at data/run/estimates/restart-<context>.rds, one for the HPC (restart-hpc.rds) and one for small local runs (restart-local.rds).

A run starts from a restart point by passing it to netsim() in place of the network estimates, with the reinitialization module and a start step:

control <- control_msm(
  start          = restart_time,       # 2, from R/shared_variables.R
  nsteps         = intervention_end,
  initialize.FUN = reinit_msm
)
sim <- netsim(readRDS(path_to_restart), param, init, control)

A restart point is not a checkpoint. A checkpoint is temporary crash protection inside one netsim() call; a restart point is a permanent input to later runs (see Running Network Models with Checkpoints).

How it is made

make_restart_point_hiv() in R/C-calibration/utils-restart.R wraps EpiModel::make_restart_point(). It keeps one simulation and its last time step, and shifts every attribute that holds a time step so that the old last step becomes step 1 and the restarted run continues at step 2. It finds those attributes by name: those ending in .last or .time (and .due on the v4.0.x Template). If you add an attribute that stores a time step, give it one of those suffixes or add its pattern to time_prefixes. An attribute that is missed keeps its old absolute value, which lies thousands of steps in the future after the restart: in one of our models an injection due date was missed this way, and re-dosing quietly stopped.

3-choose_restart.R picks which simulation to keep. For each candidate it averages each calibration target over the last year, sums the squared deviations from the targets, and rules out any simulation in which an STI's incidence fell below 25% of its target, since an STI that has nearly died out does not recover after a restart. The simulation with the lowest sum becomes the restart point. Because the deviations are not scaled, targets with large values (STI incidence per 100 person-years) dominate the choice; if that matters for your project, scale each deviation by its target before summing.

The runs that produce candidates must save their run state, save.run = TRUE in control_msm(), which is the default. Scenario campaigns that only need merged results use save.run = FALSE.

The two restart points of a calibration

The first restart point (calibration phase 2)

After the ballpark phase, take the restart point from the best ballpark scenario; no new simulations are needed. Set scenario_name at the top of 3-choose_restart.R to that scenario's ID and run the script from the project root in a batch job on the HPC, where the simulation files are. Copy restart-hpc.rds back to your computer as well.

For local work, run 1-ballpark_calib.R on your computer, then 3-choose_restart.R with hpc_context <- FALSE and the scenario you want; it saves restart-local.rds.

The final restart point (calibration phase 4)

When calibration has converged and the calibrated values are in data/input/model_parameters.csv, run R/C-calibration/workflow-restart_point.R (added to the Template in October 2026; older projects can copy it from the Template). Its workflow has five steps:

  1. Restore the project's packages from renv.lock.hpc (as in every workflow).
  2. Run 500 replications of the model from scratch to calibration_end, 8 per array task.
  3. Merge them into data/run/calibration/merged_tibbles/df__empty_scenario.rds.
  4. Run 3-choose_restart.R, which saves the best one to data/run/estimates/restart-hpc.rds.
  5. Run process_calibs.R, which writes data/run/calibration/calib_assess.csv for the pool.

At full scale, expect a few hours. Before you deploy it, on the HPC:

cd /projects/epimodel/<netid>/<Project>/data/run
cp -n estimates/restart-hpc.rds estimates/restart-hpc.rds.$(date +%Y%m%d).bak
mkdir -p calibration_archived_$(date +%Y%m%d)
mv calibration/sim__empty_scenario__*.rds calibration/merged_tibbles/df__empty_scenario.rds calibration_archived_$(date +%Y%m%d)/

The first line keeps a copy of the restart point the workflow will overwrite. The others move the previous pool out of the way: the merge step reads every matching file in the folder, so leftover simulations from an earlier run would be mixed into the new pool. Then deploy as usual (build the workflow, push the code and renv.lock.hpc, pull on the HPC, copy the workflow folder, start it). When the END email arrives, copy restart-hpc.rds and calib_assess.csv to your computer and check calib_assess.csv before using the new restart point.

When to make a new one

A restart point carries the state of the model that produced it. Make a new one, rather than patching the old one, whenever:

  • You add attributes. On a restart, EpiModel restores each node's attributes from the saved run without consulting get_default_attrs(). The restarted nodes lack any attribute added since, so a run either stops when a module asks for it or carries NA for those nodes.
  • Calibrated or other parameters that shape the burn-in change. The saved population and epidemic reflect the old values.
  • The engine changes the burn-in dynamics, for example a new or reworked module.
  • You move to a new EpiModel minor version. Starting with 2.7.0, netsim() will not restart from an object saved under a different major or minor version (a 2.6.x restart point on 2.7.0, for example), so remake the restart point after the upgrade. An old one stops the run with "EpiModel is version v2.7.0 but the restart object comes from version v(<2.7)".

When a model change adds attributes and also needs recalibration, the order is: make a restart point with the new model (so the calibration simulations have the new attributes), recalibrate, put the calibrated values in your overrides, and make the final restart point again. The scenarios run against that last one.

Parameters when restarting

Build param from your parameter files, as R/netsim_settings.R does, never from the restart point (readRDS(path_to_restart)$param). A restart point made before a parameter change carries the old values, and a run built from them is the old model with no error anywhere.

Starting with EpiModel 2.7.0 (released October 16, 2026), netsim() takes the parameters of a restarted run only from its param argument, which must hold all of the model's parameters. Parameters that an initialization module adds with set_param() are not carried over. EpiModelHIV 3.3.3 and later handle the one such parameter, time.unit, in reinit_msm(); if you write your own initialization or reinitialization module, set any such parameters again there.

Next: Programmatically Defining Scenarios.

Clone this wiki locally