Skip to content

Commit 8dea889

Browse files
authored
Add tax-exempt interest calibration targets (#881)
1 parent 2387a16 commit 8dea889

5 files changed

Lines changed: 57 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Re-enabled SOI aggregate and AGI-bin targets for tax-exempt interest income and SOI aggregate targets for charitable deductions in calibration.

policyengine_us_data/calibration/target_config.yaml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,18 @@ include:
241241
- variable: tax_unit_count
242242
geo_level: national
243243
domain_variable: adjusted_gross_income,taxable_interest_income
244+
- variable: tax_exempt_interest_income
245+
geo_level: national
246+
domain_variable: tax_exempt_interest_income
247+
- variable: tax_exempt_interest_income
248+
geo_level: national
249+
domain_variable: adjusted_gross_income,tax_exempt_interest_income
250+
- variable: tax_unit_count
251+
geo_level: national
252+
domain_variable: tax_exempt_interest_income
253+
- variable: tax_unit_count
254+
geo_level: national
255+
domain_variable: adjusted_gross_income,tax_exempt_interest_income
244256
- variable: refundable_ctc
245257
geo_level: national
246258
domain_variable: refundable_ctc
@@ -300,6 +312,12 @@ include:
300312
domain_variable: ssn_card_type
301313

302314
# === NATIONAL — SOI deduction totals (non-reform) ===
315+
- variable: charitable_deduction
316+
geo_level: national
317+
domain_variable: charitable_deduction
318+
- variable: tax_unit_count
319+
geo_level: national
320+
domain_variable: charitable_deduction
303321
- variable: medical_expense_deduction
304322
geo_level: national
305323
domain_variable: medical_expense_deduction,tax_unit_itemizes
@@ -335,7 +353,7 @@ include:
335353
# NOT INCLUDED — high error or tension (from prior validation)
336354
# =====================================================================
337355
# rental_income (20%), income_tax_before_credits (21%),
338-
# salt SOI (102%), tax_exempt_interest_income (61%),
356+
# salt SOI (102%),
339357
# taxable_ira_distributions (68%), taxable_social_security (55%),
340358
# person_count by AGI bins (100%)
341359
#
@@ -344,3 +362,4 @@ include:
344362
# dividend_income (was 26% rel-err)
345363
# qualified_dividend_income (was 29%)
346364
# taxable_interest_income (was 61%)
365+
# tax_exempt_interest_income (was 61%)

policyengine_us_data/db/etl_irs_soi.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,7 @@ def _skip_coarse_state_agi_person_count_target(geo_type: str, agi_stub: int) ->
174174
# figure into a slot the district targets treat as net, creating a
175175
# +40.7% / +26.1% / +3.1% definitional mismatch at 2023 values.
176176
WORKBOOK_NATIONAL_DOMAIN_TARGETS = {
177+
"charitable_deduction": "charitable_contributions_deductions",
177178
"dividend_income": "ordinary_dividends",
178179
"income_tax_before_credits": "income_tax_before_credits",
179180
"qualified_dividend_income": "qualified_dividends",
@@ -192,6 +193,7 @@ def _skip_coarse_state_agi_person_count_target(geo_type: str, agi_stub: int) ->
192193
"net_capital_gains",
193194
"dividend_income",
194195
"qualified_dividend_income",
196+
"tax_exempt_interest_income",
195197
"taxable_interest_income",
196198
)
197199

tests/unit/calibration/test_target_config.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ def test_training_config_includes_national_capital_income_agi_targets(self):
222222
"net_capital_gains",
223223
"dividend_income",
224224
"qualified_dividend_income",
225+
"tax_exempt_interest_income",
225226
"taxable_interest_income",
226227
]
227228
for variable in variables:
@@ -259,6 +260,30 @@ def test_training_config_includes_national_qbi_deduction_targets(self):
259260
"domain_variable": "qualified_business_income_deduction",
260261
} in include_rules
261262

263+
def test_training_config_includes_national_charitable_deduction_targets(
264+
self,
265+
):
266+
config = load_target_config(
267+
str(
268+
Path(__file__).resolve().parents[3]
269+
/ "policyengine_us_data"
270+
/ "calibration"
271+
/ "target_config.yaml"
272+
)
273+
)
274+
275+
include_rules = config["include"]
276+
assert {
277+
"variable": "charitable_deduction",
278+
"geo_level": "national",
279+
"domain_variable": "charitable_deduction",
280+
} in include_rules
281+
assert {
282+
"variable": "tax_unit_count",
283+
"geo_level": "national",
284+
"domain_variable": "charitable_deduction",
285+
} in include_rules
286+
262287
def test_training_config_includes_medicare_part_b_target(self):
263288
config = load_target_config(
264289
str(

tests/unit/test_etl_irs_soi_overlay.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
)
1515
from policyengine_us_data.db.etl_irs_soi import (
1616
GEOGRAPHY_FILE_TARGET_SPECS,
17+
WORKBOOK_NATIONAL_DOMAIN_TARGETS,
1718
get_geography_soi_year,
1819
get_national_geography_soi_agi_targets,
1920
get_national_geography_soi_target,
@@ -193,6 +194,13 @@ def fake_get_tracked_soi_row(variable, requested_year, **kwargs):
193194
assert float(count_rows.iloc[0]["value"]) == 50.0
194195

195196

197+
def test_workbook_domain_targets_include_charitable_deduction():
198+
assert (
199+
WORKBOOK_NATIONAL_DOMAIN_TARGETS["charitable_deduction"]
200+
== "charitable_contributions_deductions"
201+
)
202+
203+
196204
def test_skip_coarse_state_agi_person_count_target_only_for_state_stub_9():
197205
assert _skip_coarse_state_agi_person_count_target("state", 9) is True
198206
assert _skip_coarse_state_agi_person_count_target("state", 8) is False
@@ -470,6 +478,7 @@ def test_load_national_geography_ctc_agi_targets_creates_capital_income_domains(
470478
"net_capital_gains",
471479
"dividend_income",
472480
"qualified_dividend_income",
481+
"tax_exempt_interest_income",
473482
"taxable_interest_income",
474483
]
475484
domains = [f"adjusted_gross_income,{variable}" for variable in variables]

0 commit comments

Comments
 (0)