Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
b475471
Add calibration package checkpointing, target config, and hyperparame…
baogorek Feb 17, 2026
3449c81
Ignore all calibration run outputs in storage/calibration/
baogorek Feb 17, 2026
e91eda3
Add --lambda-l0 to Modal runner, fix load_dataset dict handling
baogorek Feb 18, 2026
76fd75d
Add --package-path support to Modal runner
baogorek Feb 18, 2026
41abe20
Add --log-freq for per-epoch calibration logging, fix output dir
baogorek Feb 18, 2026
f7bd1d8
Create log directory before writing calibration log
baogorek Feb 18, 2026
10ad716
Add debug logging for CLI args and command in package path
baogorek Feb 18, 2026
b3ba3c8
Fix chunked epoch display and rename Modal output files
baogorek Feb 18, 2026
e0d737e
Replace per-clone Microsimulation with per-state precomputation
baogorek Feb 18, 2026
7510042
Add Modal Volume support and fix CUDA OOM fragmentation
baogorek Feb 19, 2026
b148c7b
Restrict targets to age demographics only for debugging
baogorek Feb 19, 2026
13a55e2
Add include mode to target config, switch to age-only
baogorek Feb 20, 2026
b8d7a56
Switch target config to finest-grain include (~18K targets)
baogorek Feb 20, 2026
8287e12
Fix at-large district geoid mismatch (7 districts had 0 estimates)
baogorek Feb 20, 2026
0bfa2b6
Add CLI package validator, drop impossible roth_ira_contributions target
baogorek Feb 20, 2026
45744f5
Add population-based initial weights for L0 calibration
baogorek Feb 20, 2026
97c193a
Drop inflated dollar targets, add ACA PTC, save full package
baogorek Feb 20, 2026
7dcffbb
Remove redundant --puf-dataset flag, add national targets
baogorek Feb 20, 2026
4ef4877
fixing the stacked dataset builder
baogorek Feb 20, 2026
96021db
Derive cds_ordered from cd_geoid array instead of database query
baogorek Feb 20, 2026
755e796
Update notebook outputs from successful calibration pipeline run
baogorek Feb 21, 2026
17e3338
Fix takeup draw ordering mismatch between matrix builder and stacked …
baogorek Feb 24, 2026
8e63d62
checkpoint with aca_ptc randomness working
baogorek Feb 24, 2026
1957af8
verify script
baogorek Feb 24, 2026
c0ac835
Prevent clone-to-CD collisions in geography assignment
baogorek Feb 24, 2026
90e8108
checkpoint
baogorek Feb 25, 2026
d13bc00
Fix cross-state cache pollution in matrix builder precomputation
baogorek Feb 25, 2026
d00cf29
bens work on feb 25
baogorek Feb 26, 2026
85ac5e2
Selective county-level precomputation via COUNTY_DEPENDENT_VARS
juaristi22 Feb 26, 2026
4d767aa
minor fixes
juaristi22 Feb 26, 2026
dc9f318
small optimizations
juaristi22 Feb 26, 2026
33db6e2
Parallelize clone loop in build_matrix() via ProcessPoolExecutor
juaristi22 Feb 26, 2026
e7db224
Migrate from changelog_entry.yaml to towncrier fragments (#550)
MaxGhenis Feb 24, 2026
787cbcb
Add end-to-end test for calibration database build pipeline (#556)
MaxGhenis Feb 26, 2026
5c1bfe3
Parallelize clone loop in build_matrix() via ProcessPoolExecutor
juaristi22 Feb 26, 2026
f2fa0cf
add target config
baogorek Feb 27, 2026
17cd947
Reorganize calibration modules from local_area_calibration to calibra…
baogorek Feb 27, 2026
ccaefa9
Fix worker stdout pollution breaking JSON result parsing
baogorek Feb 27, 2026
e84fde9
Add volume-based verification after worker builds
baogorek Feb 27, 2026
b244a30
Fix at-large district GEOID round-trip conversion
baogorek Feb 27, 2026
50c5303
Always fresh-download calibration inputs, clear stale builds
baogorek Feb 27, 2026
3319a0a
Normalize at-large district naming: 00 and 98 both map to 01
baogorek Feb 27, 2026
dc5ec04
Enable takeup re-randomization in stacked dataset H5 builds
baogorek Feb 27, 2026
6284098
Streamline calibration pipeline: rename, upload, auto-trigger
baogorek Feb 27, 2026
4d0f3a4
Add make pipeline: data → upload → calibrate → stage in one command
baogorek Feb 28, 2026
095ed9f
documentation
baogorek Feb 28, 2026
e1b6fb1
flag
baogorek Feb 28, 2026
085e0b9
changes to remote calibration runner
baogorek Mar 1, 2026
c84930c
Script cleanup, validation gating workflow, sanity checks, docs
baogorek Mar 2, 2026
5772c74
Use source-imputed dataset for H5 staging, upload it from calibration
baogorek Mar 2, 2026
c2ddafc
Fix sanity_checks H5 key lookup for group/period structure
baogorek Mar 2, 2026
dc59327
Fix stage-h5s: add ::main entrypoint to modal run
baogorek Mar 2, 2026
e7b583e
Add validation job to publish workflow, promote target, fix OOM
baogorek Mar 2, 2026
7c0259b
after county acknowledgement
baogorek Mar 3, 2026
ea9ee7b
Add provenance tracking, fix takeup rerandomization order, improve Mo…
baogorek Mar 3, 2026
6644a90
Add national H5 pipeline, remove --prebuilt-matrices flag
baogorek Mar 3, 2026
bb24b58
Fix JSON serialization crash: __version__ resolved to module
baogorek Mar 3, 2026
f9f040d
Update upload_local_area_file docstring to list all subdirectories
baogorek Mar 3, 2026
5155206
Age-only target config for national H5 experiment, fix national builder
baogorek Mar 4, 2026
59af6eb
late night work
baogorek Mar 4, 2026
9a55fc9
calibrated populaiton counts logging
juaristi22 Mar 4, 2026
d3ed4f2
saving column sums
juaristi22 Mar 4, 2026
e6b879a
removing debugging logs
juaristi22 Mar 4, 2026
937c21e
unify build_h5 with wrappers
juaristi22 Mar 4, 2026
f0e56e9
removing wrappers
juaristi22 Mar 4, 2026
3c061a0
Full targets calibration + national staging support
baogorek Mar 4, 2026
9837944
Add back save_geo_labels/load_geo_labels lost in rebase
baogorek Mar 5, 2026
5ff6357
Add missing json import for save_geo_labels/load_geo_labels
baogorek Mar 5, 2026
7d7f1ed
Add volume reload before checking national H5 exists
baogorek Mar 5, 2026
f71e874
Consolidate takeup draws to shared compute_block_takeup_for_entities
juaristi22 Mar 5, 2026
e0f49f2
Consolidate calibration pipeline duplications
juaristi22 Mar 5, 2026
6ad42f6
Regenerate uv.lock after rebase on main
juaristi22 Mar 5, 2026
6eba89d
Extract source imputation into standalone make data step
baogorek Mar 5, 2026
6e8c352
Update HF download and H5 staging to use source-imputed dataset
baogorek Mar 5, 2026
114b3d5
Save weight-averaged takeup from calibration to fix 3.4x mismatch in …
baogorek Mar 6, 2026
9d29b1a
Rebuild entity mappings from sim when running from --package-path
baogorek Mar 7, 2026
c835350
Disable non-filer-inflated calibration targets and slim stacked_datas…
baogorek Mar 10, 2026
926cd8f
Disable non-filer-inflated targets, slim stacked builder, remove is_p…
baogorek Mar 10, 2026
591d95b
Fix Modal pipeline: fresh clones, geography.npz flow, download valida…
juaristi22 Mar 11, 2026
f3f932e
linting
juaristi22 Mar 11, 2026
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
63 changes: 59 additions & 4 deletions .github/workflows/local_area_publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ on:
# push:
# branches: [main]
# paths:
# - 'policyengine_us_data/datasets/cps/local_area_calibration/**'
# - 'policyengine_us_data/calibration/**'
# - '.github/workflows/local_area_publish.yaml'
# - 'modal_app/**'
# repository_dispatch:
Expand All @@ -24,7 +24,7 @@ on:
type: boolean

# Trigger strategy:
# 1. Automatic: Code changes to local_area_calibration/ pushed to main
# 1. Automatic: Code changes to calibration/ pushed to main
# 2. repository_dispatch: Calibration workflow triggers after uploading new weights
# 3. workflow_dispatch: Manual trigger with optional parameters

Expand Down Expand Up @@ -72,5 +72,60 @@ jobs:
echo "" >> $GITHUB_STEP_SUMMARY
echo "Files have been uploaded to GCS and staged on HuggingFace." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Next step: Promote to production" >> $GITHUB_STEP_SUMMARY
echo "Trigger the **Promote Local Area H5 Files** workflow with the version from the build output." >> $GITHUB_STEP_SUMMARY
echo "### Next step: Validation runs automatically" >> $GITHUB_STEP_SUMMARY
echo "The validate-staging job will now check all staged H5s." >> $GITHUB_STEP_SUMMARY

validate-staging:
needs: publish-local-area
runs-on: ubuntu-latest
env:
HUGGING_FACE_TOKEN: ${{ secrets.HUGGING_FACE_TOKEN }}
steps:
- name: Checkout repo
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Set up uv
uses: astral-sh/setup-uv@v5

- name: Install dependencies
run: uv sync

- name: Validate staged H5s
run: |
uv run python -m policyengine_us_data.calibration.validate_staging \
--area-type states --output validation_results.csv

- name: Upload validation results to HF
run: |
uv run python -c "
from policyengine_us_data.utils.huggingface import upload
upload('validation_results.csv',
'policyengine/policyengine-us-data',
'calibration/logs/validation_results.csv')
"

- name: Post validation summary
if: always()
run: |
echo "## Validation Results" >> $GITHUB_STEP_SUMMARY
if [ -f validation_results.csv ]; then
TOTAL=$(tail -n +2 validation_results.csv | wc -l)
FAILS=$(grep -c ',FAIL,' validation_results.csv || true)
echo "- **${TOTAL}** targets validated" >> $GITHUB_STEP_SUMMARY
echo "- **${FAILS}** sanity failures" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Review in dashboard, then trigger **Promote** workflow." >> $GITHUB_STEP_SUMMARY
else
echo "Validation did not produce output." >> $GITHUB_STEP_SUMMARY
fi

- name: Upload validation artifact
uses: actions/upload-artifact@v4
with:
name: validation-results
path: validation_results.csv
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ docs/.ipynb_checkpoints/
## ACA PTC state-level uprating factors
!policyengine_us_data/storage/aca_ptc_multipliers_2022_2024.csv

## Raw input cache for database pipeline
policyengine_us_data/storage/calibration/raw_inputs/
## Calibration run outputs (weights, diagnostics, packages, config)
policyengine_us_data/storage/calibration/

## Batch processing checkpoints
completed_*.txt

## Test fixtures
!policyengine_us_data/tests/test_local_area_calibration/test_fixture_50hh.h5
!policyengine_us_data/tests/test_calibration/test_fixture_50hh.h5
oregon_ctc_analysis.py
146 changes: 140 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
.PHONY: all format test install download upload docker documentation data validate-data calibrate publish-local-area clean build paper clean-paper presentations database database-refresh promote-database promote-dataset
.PHONY: all format test install download upload docker documentation data validate-data calibrate calibrate-build publish-local-area upload-calibration upload-dataset upload-database push-to-modal build-matrices calibrate-modal calibrate-modal-national calibrate-both stage-h5s stage-national-h5 stage-all-h5s pipeline validate-staging validate-staging-full upload-validation check-staging check-sanity clean build paper clean-paper presentations database database-refresh promote-database promote-dataset promote build-h5s validate-local

GPU ?= A100-80GB
EPOCHS ?= 200
NATIONAL_GPU ?= T4
NATIONAL_EPOCHS ?= 200
BRANCH ?= $(shell git rev-parse --abbrev-ref HEAD)
NUM_WORKERS ?= 8
VERSION ?=

HF_CLONE_DIR ?= $(HOME)/huggingface/policyengine-us-data

Expand Down Expand Up @@ -79,8 +87,8 @@ promote-database:
@echo "Copied DB and raw_inputs to HF clone. Now cd to HF repo, commit, and push."

promote-dataset:
cp policyengine_us_data/storage/stratified_extended_cps_2024.h5 \
$(HF_CLONE_DIR)/calibration/stratified_extended_cps.h5
cp policyengine_us_data/storage/source_imputed_stratified_extended_cps_2024.h5 \
$(HF_CLONE_DIR)/calibration/source_imputed_stratified_extended_cps.h5
@echo "Copied dataset to HF clone. Now cd to HF repo, commit, and push."

data: download
Expand All @@ -90,20 +98,146 @@ data: download
python policyengine_us_data/datasets/puf/irs_puf.py
python policyengine_us_data/datasets/puf/puf.py
python policyengine_us_data/datasets/cps/extended_cps.py
python policyengine_us_data/calibration/create_stratified_cps.py
python policyengine_us_data/calibration/create_source_imputed_cps.py

data-legacy: data
python policyengine_us_data/datasets/cps/enhanced_cps.py
python policyengine_us_data/datasets/cps/small_enhanced_cps.py
python policyengine_us_data/datasets/cps/local_area_calibration/create_stratified_cps.py

calibrate: data
python -m policyengine_us_data.calibration.unified_calibration \
--puf-dataset policyengine_us_data/storage/puf_2024.h5
--target-config policyengine_us_data/calibration/target_config.yaml

calibrate-build: data
python -m policyengine_us_data.calibration.unified_calibration \
--target-config policyengine_us_data/calibration/target_config.yaml \
--build-only

validate-package:
python -m policyengine_us_data.calibration.validate_package

publish-local-area:
python policyengine_us_data/datasets/cps/local_area_calibration/publish_local_area.py
python policyengine_us_data/calibration/publish_local_area.py --upload

build-h5s:
python -m policyengine_us_data.calibration.publish_local_area \
--weights-path policyengine_us_data/storage/calibration/calibration_weights.npy \
--dataset-path policyengine_us_data/storage/source_imputed_stratified_extended_cps_2024.h5 \
--n-clones 430 \
--seed 42 \
--states-only

validate-local:
python -m policyengine_us_data.calibration.validate_staging \
--hf-prefix local_area_build \
--area-type states --output validation_results.csv

validate-data:
python -c "from policyengine_us_data.storage.upload_completed_datasets import validate_all_datasets; validate_all_datasets()"

upload-calibration:
python -c "from policyengine_us_data.utils.huggingface import upload_calibration_artifacts; \
upload_calibration_artifacts()"

upload-dataset:
python -c "from policyengine_us_data.utils.huggingface import upload; \
upload('policyengine_us_data/storage/source_imputed_stratified_extended_cps_2024.h5', \
'policyengine/policyengine-us-data', \
'calibration/source_imputed_stratified_extended_cps.h5')"
@echo "Dataset uploaded to HF."

upload-database:
python -c "from policyengine_us_data.utils.huggingface import upload; \
upload('policyengine_us_data/storage/calibration/policy_data.db', \
'policyengine/policyengine-us-data', \
'calibration/policy_data.db')"
@echo "Database uploaded to HF."

push-to-modal:
modal volume put local-area-staging \
policyengine_us_data/storage/calibration/calibration_weights.npy \
calibration_inputs/calibration/calibration_weights.npy --force
modal volume put local-area-staging \
policyengine_us_data/storage/calibration/stacked_blocks.npy \
calibration_inputs/calibration/stacked_blocks.npy --force
modal volume put local-area-staging \
policyengine_us_data/storage/calibration/stacked_takeup.npz \
calibration_inputs/calibration/stacked_takeup.npz --force
modal volume put local-area-staging \
policyengine_us_data/storage/calibration/policy_data.db \
calibration_inputs/calibration/policy_data.db --force
modal volume put local-area-staging \
policyengine_us_data/storage/calibration/geo_labels.json \
calibration_inputs/calibration/geo_labels.json --force
modal volume put local-area-staging \
policyengine_us_data/storage/source_imputed_stratified_extended_cps_2024.h5 \
calibration_inputs/calibration/source_imputed_stratified_extended_cps.h5 --force
@echo "All calibration inputs pushed to Modal volume."

build-matrices:
modal run modal_app/remote_calibration_runner.py::build_package \
--branch $(BRANCH)

calibrate-modal:
modal run modal_app/remote_calibration_runner.py::main \
--branch $(BRANCH) --gpu $(GPU) --epochs $(EPOCHS) \
--push-results

calibrate-modal-national:
modal run modal_app/remote_calibration_runner.py::main \
--branch $(BRANCH) --gpu $(NATIONAL_GPU) \
--epochs $(NATIONAL_EPOCHS) \
--push-results --national

calibrate-both:
$(MAKE) calibrate-modal & $(MAKE) calibrate-modal-national & wait

stage-h5s:
modal run modal_app/local_area.py::main \
--branch $(BRANCH) --num-workers $(NUM_WORKERS) \
$(if $(SKIP_DOWNLOAD),--skip-download)

stage-national-h5:
modal run modal_app/local_area.py::main_national \
--branch $(BRANCH)

stage-all-h5s:
$(MAKE) stage-h5s & $(MAKE) stage-national-h5 & wait

promote:
$(eval VERSION := $(or $(VERSION),$(shell python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")))
modal run modal_app/local_area.py::main_promote \
--branch $(BRANCH) --version $(VERSION)

validate-staging:
python -m policyengine_us_data.calibration.validate_staging \
--area-type states --output validation_results.csv

validate-staging-full:
python -m policyengine_us_data.calibration.validate_staging \
--area-type states,districts --output validation_results.csv

upload-validation:
python -c "from policyengine_us_data.utils.huggingface import upload; \
upload('validation_results.csv', \
'policyengine/policyengine-us-data', \
'calibration/logs/validation_results.csv')"

check-staging:
python -m policyengine_us_data.calibration.check_staging_sums

check-sanity:
python -m policyengine_us_data.calibration.validate_staging \
--sanity-only --area-type states --areas NC

pipeline: data upload-dataset build-matrices calibrate-both stage-all-h5s
@echo ""
@echo "========================================"
@echo "Pipeline complete. H5s are in HF staging."
@echo "Run 'Promote Local Area H5 Files' workflow in GitHub to publish."
@echo "========================================"

clean:
rm -f policyengine_us_data/storage/*.h5
rm -f policyengine_us_data/storage/*.db
Expand Down
1 change: 1 addition & 0 deletions changelog.d/add-database-build-test.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add end-to-end test for calibration database build pipeline.
8 changes: 8 additions & 0 deletions changelog.d/calibration-pipeline-improvements.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Unified calibration pipeline with GPU-accelerated L1/L0 solver, target config YAML, and CLI package validator.
Per-state and per-county precomputation replacing per-clone Microsimulation (51 sims instead of 436).
Parallel state, county, and clone loop processing via ProcessPoolExecutor.
Block-level takeup re-randomization with deterministic seeded draws.
Hierarchical uprating with ACA PTC state-level CSV factors and CD reconciliation.
Modal remote runner with Volume support, CUDA OOM fixes, and checkpointing.
Stacked dataset builder with sparse CD subsets and calibration block propagation.
Staging validation script (validate_staging.py) with sim.calculate() comparison and sanity checks.
3 changes: 3 additions & 0 deletions changelog.d/calibration-pipeline-improvements.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Geography assignment now prevents clone-to-CD collisions.
County-dependent vars (aca_ptc) selectively precomputed per county; other vars use state-only path.
Target config switched to finest-grain include mode (~18K targets).
3 changes: 3 additions & 0 deletions changelog.d/calibration-pipeline-improvements.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Cross-state cache pollution in matrix builder precomputation.
Takeup draw ordering mismatch between matrix builder and stacked builder.
At-large district geoid mismatch (7 districts had 0 estimates).
1 change: 1 addition & 0 deletions changelog.d/migrate-to-towncrier.changed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Migrated from changelog_entry.yaml to towncrier fragments to eliminate merge conflicts.
Loading
Loading