Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
42 changes: 42 additions & 0 deletions policyengine_us_data/tests/test_datasets/test_enhanced_cps.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,45 @@ def test_ecps_has_mortgage_interest():

assert sim.calculate("deductible_mortgage_interest").sum() > 1
assert sim.calculate("interest_expense").sum() > 1


def test_ecps_replicates_jct_salt_te():
from policyengine_us import Microsimulation
from policyengine_core.reforms import Reform
from policyengine_core.data import Dataset
from policyengine_us_data.datasets import EnhancedCPS_2024

reform = Reform.from_dict(
{
"gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": {
"2024-01-01.2100-12-31": 0
},
},
country_id="us",
)

baseline = Microsimulation(dataset=EnhancedCPS_2024)
reformed = Microsimulation(reform=reform, dataset=EnhancedCPS_2024)

income_tax_b = baseline.calculate(
"income_tax", period=2024, map_to="household"
)
income_tax_r = reformed.calculate(
"income_tax", period=2024, map_to="household"
)
tax_change = income_tax_r - income_tax_b
federal_tax_expenditure = tax_change.sum() / 1e9

assert abs(federal_tax_expenditure - 20) < 5
57 changes: 57 additions & 0 deletions policyengine_us_data/utils/loss.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from .soi import pe_to_soi, get_soi
import numpy as np
from policyengine_us_data.storage import STORAGE_FOLDER
from policyengine_core.reforms import Reform


def fmt(x):
Expand Down Expand Up @@ -132,6 +133,7 @@ def build_loss_matrix(dataset: type, time_period):
from policyengine_us import Microsimulation

sim = Microsimulation(dataset=dataset)
sim.default_calculation_period = time_period
hh_id = sim.calculate("household_id", map_to="person")
tax_unit_hh_id = sim.map_result(
hh_id, "person", "tax_unit", how="value_from_first_person"
Expand Down Expand Up @@ -340,10 +342,65 @@ def build_loss_matrix(dataset: type, time_period):
)
targets_array.append(row["population_under_5"])

# SALT tax expenditure targeting

_add_tax_expenditure_targets(
dataset, time_period, sim, loss_matrix, targets_array
)

if any(loss_matrix.isna().sum() > 0):
raise ValueError("Some targets are missing from the loss matrix")

if any(pd.isna(targets_array)):
raise ValueError("Some targets are missing from the targets array")

return loss_matrix, np.array(targets_array)


def _add_tax_expenditure_targets(
dataset,
time_period,
baseline_simulation,
loss_matrix: pd.DataFrame,
targets_array: list,
):
from policyengine_us import Microsimulation

# SALT deduction first

repeal_salt = Reform.from_dict(
{
"gov.irs.deductions.itemized.salt_and_real_estate.cap.JOINT": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SINGLE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SEPARATE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.SURVIVING_SPOUSE": {
"2024-01-01.2100-12-31": 0
},
"gov.irs.deductions.itemized.salt_and_real_estate.cap.HEAD_OF_HOUSEHOLD": {
"2024-01-01.2100-12-31": 0
},
},
country_id="us",
)

reform_simulation = Microsimulation(dataset=dataset, reform=repeal_salt)
reform_simulation.default_calculation_period = time_period

income_tax_b = baseline_simulation.calculate(
"income_tax", map_to="household"
).values
income_tax_r = reform_simulation.calculate(
"income_tax", map_to="household"
).values
salt_te_values = income_tax_r - income_tax_b

salt_target = 20e9

loss_matrix["jct/salt_tax_expenditure"] = salt_te_values
targets_array.append(salt_target)
Loading