From 1a152b09360e9e9e2041e8d9803e0ccbc5bd138d Mon Sep 17 00:00:00 2001 From: Max Ghenis Date: Tue, 28 Apr 2026 21:37:04 -0400 Subject: [PATCH] Add WIC calibration targets --- changelog.d/845.added.md | 1 + .../calibration/target_config.yaml | 7 ++ .../db/etl_national_targets.py | 23 ++++++ tests/unit/calibration/test_target_config.py | 18 +++++ tests/unit/test_etl_national_targets.py | 80 +++++++++++++++++++ 5 files changed, 129 insertions(+) create mode 100644 changelog.d/845.added.md diff --git a/changelog.d/845.added.md b/changelog.d/845.added.md new file mode 100644 index 000000000..aa4410590 --- /dev/null +++ b/changelog.d/845.added.md @@ -0,0 +1 @@ +Add national WIC calibration targets for FY 2024 total program costs and average monthly participation. diff --git a/policyengine_us_data/calibration/target_config.yaml b/policyengine_us_data/calibration/target_config.yaml index 154dcf878..215769c9b 100644 --- a/policyengine_us_data/calibration/target_config.yaml +++ b/policyengine_us_data/calibration/target_config.yaml @@ -151,6 +151,8 @@ include: geo_level: national - variable: unemployment_compensation geo_level: national + - variable: wic + geo_level: national # === NATIONAL — retirement contribution targets === - variable: traditional_ira_contributions @@ -232,6 +234,11 @@ include: geo_level: national domain_variable: ssn_card_type + # === NATIONAL — WIC participation count target === + - variable: person_count + geo_level: national + domain_variable: wic + # === NATIONAL — SOI deduction totals (non-reform) === - variable: medical_expense_deduction geo_level: national diff --git a/policyengine_us_data/db/etl_national_targets.py b/policyengine_us_data/db/etl_national_targets.py index a671daedb..eda6d6832 100644 --- a/policyengine_us_data/db/etl_national_targets.py +++ b/policyengine_us_data/db/etl_national_targets.py @@ -23,6 +23,11 @@ ) +WIC_NATIONAL_ANNUAL_SUMMARY_SOURCE = ( + "https://www.fns.usda.gov/sites/default/files/resource-files/wisummary-4.xlsx" +) + + def extract_national_targets(year: int = DEFAULT_YEAR): """ Extract national calibration targets from various sources. @@ -196,6 +201,13 @@ def extract_national_targets(year: int = DEFAULT_YEAR): "notes": "Housing subsidies", "year": 2024, }, + { + "variable": "wic", + "value": 7_332_200_000, + "source": WIC_NATIONAL_ANNUAL_SUMMARY_SOURCE, + "notes": "FY 2024 WIC total costs; National Level Annual Summary workbook, sheet 'Annual Participation and costs', FY 2024 row; food costs are $4.9115B", + "year": 2024, + }, { "variable": "real_estate_taxes", "value": 500e9, @@ -316,6 +328,13 @@ def extract_national_targets(year: int = DEFAULT_YEAR): "notes": "ACA Premium Tax Credit recipients", "year": 2024, }, + { + "constraint_variable": "wic", + "person_count": 6_704_000, + "source": WIC_NATIONAL_ANNUAL_SUMMARY_SOURCE, + "notes": "FY 2024 WIC average monthly participation; National Level Annual Summary workbook, sheet 'Annual Participation and costs', FY 2024 row", + "year": 2024, + }, { "constraint_variable": "spm_unit_energy_subsidy_reported", "target_variable": "household_count", @@ -738,6 +757,10 @@ def load_national_targets( stratum_notes = "National ACA Premium Tax Credit Recipients" constraint_operation = ">" constraint_value = "0" + elif constraint_var == "wic": + stratum_notes = "National WIC Recipients" + constraint_operation = ">" + constraint_value = "0" elif constraint_var == "spm_unit_energy_subsidy_reported": stratum_notes = "National LIHEAP Recipient Households" constraint_operation = ">" diff --git a/tests/unit/calibration/test_target_config.py b/tests/unit/calibration/test_target_config.py index c698e83db..156ee848b 100644 --- a/tests/unit/calibration/test_target_config.py +++ b/tests/unit/calibration/test_target_config.py @@ -245,6 +245,24 @@ def test_training_config_includes_tanf_state_and_national_count_targets(self): "domain_variable": "tanf", } in include_rules + def test_training_config_includes_wic_national_targets(self): + config = load_target_config( + str( + Path(__file__).resolve().parents[3] + / "policyengine_us_data" + / "calibration" + / "target_config.yaml" + ) + ) + + include_rules = config["include"] + assert {"variable": "wic", "geo_level": "national"} in include_rules + assert { + "variable": "person_count", + "geo_level": "national", + "domain_variable": "wic", + } in include_rules + class TestCalibrationPackageRoundTrip: def test_round_trip(self, sample_targets, tmp_path): diff --git a/tests/unit/test_etl_national_targets.py b/tests/unit/test_etl_national_targets.py index 84d8c748b..cd3b79cb5 100644 --- a/tests/unit/test_etl_national_targets.py +++ b/tests/unit/test_etl_national_targets.py @@ -199,3 +199,83 @@ def test_load_national_targets_supports_liheap_household_counts(tmp_path, monkey ).first() assert liheap_target is not None assert liheap_target.value == 5_876_646 + + +def test_load_national_targets_supports_wic_targets(tmp_path, monkeypatch): + calibration_dir = tmp_path / "calibration" + calibration_dir.mkdir() + db_uri = f"sqlite:///{calibration_dir / 'policy_data.db'}" + engine = create_database(db_uri) + + with Session(engine) as session: + national = _make_stratum(session, notes="United States") + national_id = national.stratum_id + + monkeypatch.setattr( + "policyengine_us_data.db.etl_national_targets.STORAGE_FOLDER", + tmp_path, + ) + + direct_targets_df = pd.DataFrame( + [ + { + "variable": "wic", + "value": 7_332_200_000, + "source": "https://www.fns.usda.gov/sites/default/files/resource-files/wisummary-4.xlsx", + "notes": "FY 2024 WIC total costs from FNS annual summary", + "year": 2024, + } + ] + ) + conditional_targets = [ + { + "constraint_variable": "wic", + "person_count": 6_704_000, + "source": "https://www.fns.usda.gov/sites/default/files/resource-files/wisummary-4.xlsx", + "notes": "FY 2024 WIC average monthly participation", + "year": 2024, + } + ] + + load_national_targets( + direct_targets_df=direct_targets_df, + tax_filer_df=pd.DataFrame(), + tax_expenditure_df=pd.DataFrame(), + conditional_targets=conditional_targets, + ) + + with Session(engine) as session: + wic_total_target = session.exec( + select(Target).where( + Target.stratum_id == national_id, + Target.variable == "wic", + Target.period == 2024, + ) + ).first() + assert wic_total_target is not None + assert wic_total_target.value == 7_332_200_000 + + wic_stratum = session.exec( + select(Stratum).where(Stratum.notes == "National WIC Recipients") + ).first() + assert wic_stratum is not None + + constraints = { + ( + constraint.constraint_variable, + constraint.operation, + constraint.value, + ) + for constraint in wic_stratum.constraints_rel + } + assert ("wic", ">", "0") in constraints + + wic_count_target = session.exec( + select(Target).where( + Target.stratum_id == wic_stratum.stratum_id, + Target.variable == "person_count", + Target.period == 2024, + ) + ).first() + assert wic_count_target is not None + assert wic_count_target.value == 6_704_000