Conversation
subsample exported every stored value, calculated ones included, and loaded them all back as inputs. A formula result calculated before subsampling then replaced its formula for good: it was carried over past the formula's end and survived apply_reform and later set_input calls, so results after subsampling depended on what had been calculated before. It now exports the values the simulation was given (loaded from the dataset or passed to set_input), for variables with a formula too, so formula-backed structural IDs from the dataset are still kept. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 2, 2026
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
subsamplerebuilt the simulation fromto_input_dataframe(include_computed_variables=True), that is, from every stored value, calculated ones included, all reloaded as inputs. A formula result calculated before subsampling therefore replaced its formula for good, and results after subsampling depended on what had been calculated before:apply_reform(_invalidate_all_cacheskeepsset_inputvalues) and laterset_inputcalls on its inputs.Found while reviewing #562 (soundness review, finding 7).
The rule
subsamplenow exports the values the simulation was given: every period recorded byset_input(dataset loading included) and still stored, on the branches it reads, for every variable, including variables with a formula. So formula-backed structural IDs that come from the dataset (the reason for 56c8b82) and dataset values overriding a formula are kept, and calculated values are not.to_input_dataframeis unchanged; its loop moved into_to_person_dataframe, which both use.Invariants
subsample, the subsampled simulation stores exactly what a simulation subsampled straight after loading stores, and every later result agrees. Property test:tests/core/test_subsample_inputs_only_property.py(Hypothesis, 150 examples: calculations of formula, group, weight and input variables at the dataset year and others, carry-over on and off, then later requests). It fails on master.Downstream impact
Real runs on master b78b0ba and on all three of #571/#572/#573 merged together (scratch merge 37aadada), each output compared array by array (
compare.py). The PE-US 2026 run was also repeated on each branch alone, and the 2035 run on #572 alone; all identical too.No published pipeline calls
subsample(policyengine.py and the APIs build one simulation per year); policyengine-us uses it in its microsimulation tests and docs.The PE-US runs subsample straight after loading (
--subsample=3000), so they also show that this branch samples the same households with the same weights as master there.Tests
tests/core/test_subsample_inputs_only.py: 6 regressions (4 fail on master: carry-over past a formula's end, stored values, following a new input, following a reform; 2 pin kept behaviour: dataset values for a formula variable, formulas recomputed on the sample).tests/core/test_subsample_inputs_only_property.py, behindpytest.importorskip("hypothesis").Composition
Reads the
_user_input_keysrecord. #561 keeps that record in step with storage (deletes, clones, subsample reset); with it merged, values deleted from storage after being set also stop being exported. Until then the existing intersection with stored periods covers the common case.axiom: n/a: core engine, no policy encoding
🤖 Generated with Claude Code