Skip to content

Commit e019dce

Browse files
committed
Remove SSI fiscal-year calibration variable
1 parent 8663831 commit e019dce

9 files changed

Lines changed: 24 additions & 225 deletions

File tree

policyengine_us_data/calibration/sanity_checks.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@
3636
"income_tax_before_credits",
3737
]
3838

39-
COMPUTED_KEY_MONETARY_VARS = [
40-
"ssi_federal_fiscal_year_outlays",
41-
]
39+
COMPUTED_KEY_MONETARY_VARS = []
4240

4341
TAKEUP_VARS = [
4442
"takes_up_snap_if_eligible",
@@ -665,6 +663,9 @@ def _append_finite_check(var: str, vals) -> None:
665663

666664

667665
def _computed_key_monetary_values(h5_path: str, period: int) -> dict[str, np.ndarray]:
666+
if not COMPUTED_KEY_MONETARY_VARS:
667+
return {}
668+
668669
try:
669670
from policyengine_us import Microsimulation
670671

policyengine_us_data/calibration/target_config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ include:
205205
geo_level: national
206206
- variable: social_security_survivors
207207
geo_level: national
208-
- variable: ssi_federal_fiscal_year_outlays
208+
- variable: ssi
209209
geo_level: national
210210
- variable: person_count
211211
geo_level: national

policyengine_us_data/db/etl_national_targets.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,11 @@
2727
get_geographic_strata,
2828
)
2929
from policyengine_us_data.utils.ssi_targets import (
30-
SSI_PAYMENT_TARGET_SOURCE,
30+
SSI_CBO_TARGET_SOURCE,
3131
SSI_RECIPIENT_TARGET_NOTES,
3232
SSI_RECIPIENT_TARGET_SOURCE,
3333
SSI_RECIPIENT_TARGET_YEAR,
3434
SSI_RECIPIENT_TARGETS_2024,
35-
get_ssi_payment_target_notes,
36-
scale_ssi_fiscal_year_target_for_single_year_data,
3735
)
3836
from policyengine_us_data.utils.target_variables import (
3937
target_variable_components,
@@ -781,14 +779,13 @@ def extract_national_targets(year: int = DEFAULT_YEAR):
781779
"income_tax_positive",
782780
"snap",
783781
"social_security",
784-
"ssi_federal_fiscal_year_outlays",
782+
"ssi",
785783
"unemployment_compensation",
786784
]
787785

788786
# Mapping from target variable to CBO parameter name (when different)
789787
cbo_param_name_map = {
790788
"income_tax_positive": "income_tax", # CBO param is income_tax
791-
"ssi_federal_fiscal_year_outlays": "ssi",
792789
}
793790

794791
cbo_targets = []
@@ -800,12 +797,8 @@ def extract_national_targets(year: int = DEFAULT_YEAR):
800797
).calibration.gov.cbo._children[param_name]
801798
source = "CBO Budget Projections"
802799
notes = f"CBO projection for {variable_name}"
803-
if variable_name == "ssi_federal_fiscal_year_outlays":
804-
value = scale_ssi_fiscal_year_target_for_single_year_data(
805-
value, time_period
806-
)
807-
source = SSI_PAYMENT_TARGET_SOURCE
808-
notes = get_ssi_payment_target_notes(time_period)
800+
if variable_name == "ssi":
801+
source = SSI_CBO_TARGET_SOURCE
809802
cbo_targets.append(
810803
{
811804
"variable": variable_name,
@@ -951,14 +944,6 @@ def load_national_targets(
951944
for _, target_data in direct_targets_df.iterrows():
952945
target_year = target_data["year"]
953946
_register_target_variable(session, target_data["variable"])
954-
if target_data["variable"] == "ssi_federal_fiscal_year_outlays":
955-
_deactivate_replaced_national_target(
956-
session,
957-
stratum_id=us_stratum.stratum_id,
958-
old_variable="ssi",
959-
new_variable="ssi_federal_fiscal_year_outlays",
960-
period=target_year,
961-
)
962947
# Check if target already exists
963948
existing_target = session.exec(
964949
select(Target).where(

policyengine_us_data/utils/loss.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
from policyengine_us_data.utils.soi import pe_to_soi, get_soi, get_tracked_soi_row
2929
from policyengine_us_data.utils.ssi_targets import (
3030
SSI_RECIPIENT_TARGETS_2024,
31-
scale_ssi_fiscal_year_target_for_single_year_data,
3231
)
3332
from policyengine_us_data.utils.target_variables import (
3433
target_variable_components,
@@ -100,13 +99,12 @@
10099
"income_tax_positive",
101100
"snap",
102101
"social_security",
103-
"ssi_federal_fiscal_year_outlays",
102+
"ssi",
104103
"unemployment_compensation",
105104
]
106105

107106
CBO_PARAM_NAME_MAP = {
108107
"income_tax_positive": "income_tax",
109-
"ssi_federal_fiscal_year_outlays": "ssi",
110108
}
111109

112110
HARD_CODED_TOTALS = {
@@ -251,12 +249,9 @@ def _add_ssi_recipient_targets(loss_matrix, targets_array, sim, time_period):
251249

252250
def _cbo_program_target_value(sim, variable_name: str, time_period):
253251
param_name = CBO_PARAM_NAME_MAP.get(variable_name, variable_name)
254-
value = sim.tax_benefit_system.parameters(
255-
time_period
256-
).calibration.gov.cbo._children[param_name]
257-
if variable_name == "ssi_federal_fiscal_year_outlays":
258-
return scale_ssi_fiscal_year_target_for_single_year_data(value, time_period)
259-
return value
252+
return sim.tax_benefit_system.parameters(time_period).calibration.gov.cbo._children[
253+
param_name
254+
]
260255

261256

262257
ACA_SPENDING_TARGETS = {

policyengine_us_data/utils/ssi_targets.py

Lines changed: 0 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,8 @@
11
"""Shared SSI calibration targets."""
22

3-
from datetime import date, timedelta
4-
53
SSI_CBO_TARGET_SOURCE = (
64
"https://www.cbo.gov/system/files/2026-02/51313-2026-02-ssi.xlsx"
75
)
8-
SSI_PAYMENT_TIMING_SOURCE = "https://www.ssa.gov/oact/ssir/SSI24/IV_C_Payments.html"
9-
SSI_PAYMENT_RULE_SOURCE = "https://www.ssa.gov/OP_Home/cfr20/416/416-0502.htm"
10-
SSI_PAYMENT_TARGET_SOURCE = (
11-
f"{SSI_CBO_TARGET_SOURCE}; {SSI_PAYMENT_TIMING_SOURCE}; {SSI_PAYMENT_RULE_SOURCE}"
12-
)
13-
14-
15-
def _as_fiscal_year(year) -> int:
16-
return int(str(year)[:4])
17-
18-
19-
def _is_new_years_day_observed(day: date) -> bool:
20-
new_years_day = date(day.year, 1, 1)
21-
next_new_years_day = date(day.year + 1, 1, 1)
22-
return (
23-
day == new_years_day
24-
or (new_years_day.weekday() == 6 and day == date(day.year, 1, 2))
25-
or (next_new_years_day.weekday() == 5 and day == date(day.year, 12, 31))
26-
)
27-
28-
29-
def _is_labor_day(day: date) -> bool:
30-
return day.month == 9 and day.weekday() == 0 and day.day <= 7
31-
32-
33-
def _is_federal_holiday_affecting_ssi_payment(day: date) -> bool:
34-
return _is_new_years_day_observed(day) or _is_labor_day(day)
35-
36-
37-
def _ssi_payment_date(year: int, month: int) -> date:
38-
payment_date = date(year, month, 1)
39-
while payment_date.weekday() >= 5 or _is_federal_holiday_affecting_ssi_payment(
40-
payment_date
41-
):
42-
payment_date -= timedelta(days=1)
43-
return payment_date
44-
45-
46-
def _ssi_fiscal_year_benefit_months(year) -> list[date]:
47-
fiscal_year = _as_fiscal_year(year)
48-
fiscal_year_start = date(fiscal_year - 1, 10, 1)
49-
fiscal_year_end = date(fiscal_year, 9, 30)
50-
51-
benefit_months = []
52-
for calendar_year in (fiscal_year - 1, fiscal_year):
53-
for month in range(1, 13):
54-
payment_day = _ssi_payment_date(calendar_year, month)
55-
if fiscal_year_start <= payment_day <= fiscal_year_end:
56-
benefit_months.append(date(calendar_year, month, 1))
57-
return benefit_months
58-
59-
60-
def get_ssi_fiscal_year_payment_count(year) -> int:
61-
"""Return SSI benefit months with payment dates in the federal fiscal year."""
62-
return len(_ssi_fiscal_year_benefit_months(year))
63-
64-
65-
def get_ssi_single_year_available_payment_count(year) -> int:
66-
"""Return fiscal-year SSI benefit months available from a single-year H5."""
67-
fiscal_year = _as_fiscal_year(year)
68-
return sum(
69-
benefit_month.year == fiscal_year
70-
for benefit_month in _ssi_fiscal_year_benefit_months(year)
71-
)
72-
73-
74-
def scale_ssi_fiscal_year_target_for_single_year_data(value, year) -> float:
75-
"""Scale full fiscal-year SSI outlays to months computable from one H5 year."""
76-
return (
77-
float(value)
78-
* get_ssi_single_year_available_payment_count(year)
79-
/ get_ssi_fiscal_year_payment_count(year)
80-
)
81-
82-
83-
def get_ssi_payment_target_notes(year) -> str:
84-
fiscal_year = _as_fiscal_year(year)
85-
available_count = get_ssi_single_year_available_payment_count(year)
86-
payment_count = get_ssi_fiscal_year_payment_count(year)
87-
return (
88-
"CBO SSI federal fiscal-year outlays scaled to the benefit months "
89-
"computable from a single-year PolicyEngine-US-data H5 using "
90-
"policyengine-us ssi_federal_fiscal_year_outlays; "
91-
f"FY{fiscal_year} has {payment_count} SSI benefit months paid in the "
92-
f"federal fiscal year, of which {available_count} are benefit months "
93-
f"in calendar year {fiscal_year}"
94-
)
956

967

978
SSI_RECIPIENT_TARGET_YEAR = 2024

tests/unit/calibration/test_hourly_wage_income_consistency.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,14 @@ def test_run_sanity_checks_adds_hourly_wage_income_consistency(tmp_path):
6262
assert by_check["hourly_wage_income_consistency_overtime"]["status"] == "WARN"
6363

6464

65-
def test_run_sanity_checks_keeps_raw_ssi_and_checks_computed_outlays(
66-
tmp_path, monkeypatch
67-
):
65+
def test_run_sanity_checks_keeps_raw_ssi_without_computed_outlays(tmp_path):
6866
h5_path = tmp_path / "sample.h5"
6967
with h5py.File(h5_path, "w") as h5:
7068
_write_period_dataset(h5, "household_weight", [1.0, 1.0])
7169
_write_period_dataset(h5, "ssi", [100.0, 0.0])
7270

73-
monkeypatch.setattr(
74-
"policyengine_us_data.calibration.sanity_checks._computed_key_monetary_values",
75-
lambda h5_path, period: {
76-
"ssi_federal_fiscal_year_outlays": np.array([100.0, np.inf])
77-
},
78-
)
79-
8071
diagnostics = run_sanity_checks(str(h5_path), period=2024)
8172
by_check = {diagnostic["check"]: diagnostic for diagnostic in diagnostics}
8273

8374
assert by_check["no_nan_inf_ssi"]["status"] == "PASS"
84-
assert by_check["no_nan_inf_ssi_federal_fiscal_year_outlays"]["status"] == "FAIL"
75+
assert "no_nan_inf_ssi_federal_fiscal_year_outlays" not in by_check

tests/unit/calibration/test_loss_targets.py

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,6 @@
4242
from policyengine_us_data.db import etl_national_targets
4343
from policyengine_us_data.utils.ssi_targets import (
4444
SSI_RECIPIENT_TARGETS_2024,
45-
get_ssi_fiscal_year_payment_count,
46-
get_ssi_single_year_available_payment_count,
47-
scale_ssi_fiscal_year_target_for_single_year_data,
4845
)
4946

5047

@@ -381,28 +378,10 @@ def test_add_ssi_recipient_targets_adds_total_and_age_counts():
381378
)
382379

383380

384-
def test_ssi_payment_targets_scale_to_single_year_fiscal_year_coverage():
385-
assert get_ssi_fiscal_year_payment_count(2024) == 11
386-
assert get_ssi_single_year_available_payment_count(2024) == 9
387-
assert get_ssi_fiscal_year_payment_count(2025) == 12
388-
assert get_ssi_single_year_available_payment_count(2025) == 9
389-
assert get_ssi_fiscal_year_payment_count(2028) == 13
390-
assert get_ssi_single_year_available_payment_count(2028) == 10
391-
392-
assert scale_ssi_fiscal_year_target_for_single_year_data(
393-
57_000_000_000, 2024
394-
) == pytest.approx(57_000_000_000 * 9 / 11)
395-
assert scale_ssi_fiscal_year_target_for_single_year_data(
396-
75_400_000_000, 2028
397-
) == pytest.approx(75_400_000_000 * 10 / 13)
398-
399-
400-
def test_legacy_cbo_ssi_target_uses_single_year_fiscal_year_coverage():
381+
def test_legacy_cbo_ssi_target_uses_cbo_projection():
401382
sim = _FakeCBOProgramTargetSimulation()
402383

403-
assert _cbo_program_target_value(
404-
sim, "ssi_federal_fiscal_year_outlays", 2024
405-
) == pytest.approx(57_000_000_000 * 9 / 11)
384+
assert _cbo_program_target_value(sim, "ssi", 2024) == 57_000_000_000
406385
assert _cbo_program_target_value(sim, "snap", 2024) == 1_000.0
407386

408387

tests/unit/calibration/test_target_config.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -546,10 +546,7 @@ def test_training_config_includes_ssi_recipient_count_targets(self):
546546
)
547547

548548
include_rules = config["include"]
549-
assert {
550-
"variable": "ssi_federal_fiscal_year_outlays",
551-
"geo_level": "national",
552-
} in include_rules
549+
assert {"variable": "ssi", "geo_level": "national"} in include_rules
553550
assert {
554551
"variable": "person_count",
555552
"geo_level": "national",

0 commit comments

Comments
 (0)