Recalibrate a location
Recalibration is needed when model logic changes in a way that shifts fertility or contraceptive dynamics: the conception pipeline, sexual activity or contraception update logic, new data sources, or a new location. It is not needed for bug fixes that restore intended behavior, new result tracking that does not affect dynamics, or documentation and test changes.
All commands below are run from the repository root.
1. Save current baselines
Before changing anything, snapshot the existing parameters so you can compare afterwards:
python fpsim/locations/compare_calib_pars.py --saveThis writes a JSON snapshot per location to fpsim/locations/calib_baselines/.
2. Run the calibration
For all nine locations:
SCIRIS_BACKEND=agg python fpsim/locations/calibrate_all.pyFor a single location:
SCIRIS_BACKEND=agg python fpsim/locations/calibrate_all.py --location kenyaUseful options:
| Option | Effect |
|---|---|
--trials |
Optuna trials per location (default 200) |
--workers |
Parallel workers (defaults to every core) |
--agents |
Agents per simulation (default 5000) |
The default of 200 trials is low for a 26-dimensional search. If you have the compute, use considerably more; on a 120-core machine, 2000 trials across all nine locations takes roughly half an hour.
Each location’s result is written to fpsim/locations/calib_results/<location>.obj as soon as it finishes, so a run that is interrupted does not lose completed locations. Each location also keeps its Optuna study, so an interrupted location resumes rather than restarting.
3. Compare parameters
python fpsim/locations/compare_calib_pars.py --verboseThis flags parameters that moved more than 30% (--tolerance to change).
Expect exposure_age and exposure_parity knots to move substantially while the curve shape stays similar – judge them by shape. The scalars (exposure_factor, fecundity_low/fecundity_high) are the ones to scrutinize.
Treat these as red flags:
- A scalar parameter changing by more than 2x
exposure_factoror fecundity landing on a bound- Best mismatch clearly worse than the previous calibration
4. Inspect the fit visually
python fpsim/locations/run_calibrated_location.py kenyaThis plots model output against data for mCPR, ASFR, total fertility rate, birth spacing, age at first birth, and method mix. Do this before accepting a calibration; mismatch alone will not tell you that a curve is the wrong shape.
5. Update the location files
python fpsim/locations/calibrate_all.py --updateThis rewrites each location’s make_calib_pars() from the saved results. Parameters the generator cannot produce – method_weights and dur_postpartum – are carried over from the existing file, and each rewritten file is reloaded and checked against what it defined before. If anything would be lost, the original is restored and the location is skipped with a message naming the missing parameters.
If a location is skipped, read the reason rather than reaching for --force. Forcing the overwrite drops the hand-tuned parameters, which has previously caused large and confusing differences in results.
6. Save new baselines
python fpsim/locations/compare_calib_pars.py --save7. Regenerate test baselines
Recalibration changes simulation output, so the test baselines need regenerating:
cd tests && python update_baselineKey files
| File | Purpose |
|---|---|
fpsim/locations/calibrate_all.py |
Run calibration and update location files |
fpsim/locations/compare_calib_pars.py |
Compare parameters between versions |
fpsim/locations/run_calibrated_location.py |
Run and plot a calibrated model |
fpsim/locations/calib_results/*.obj |
Saved results (best parameters and mismatch) |
fpsim/locations/calib_baselines/*.json |
Parameter baselines for regression checking |
fpsim/locations/<location>/<location>.py |
Location-specific calibrated parameters |
tests/test_parameters.py |
Parameter coverage and regression tests |
See also
- Calibration for what is being fitted and why