Skip to content

Commit 2c056ff

Browse files
committed
Simplify rebate calculation and rename for consistency
- Remove redundant where statement (phaseout_percentage already handles cutoff) - Use lowercase for phaseout_width (not a constant) - Rename ca_aei_rebate_base to ca_aei_rebate_base_household for consistency
1 parent d85611b commit 2c056ff

1 file changed

Lines changed: 4 additions & 110 deletions

File tree

us/states/ca/aei_rebate/aei_rebate_analysis.ipynb

Lines changed: 4 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@
8686
}
8787
},
8888
"outputs": [],
89-
"source": "def create_aei_reform():\n \"\"\"\n Creates a PolicyEngine reform that adds the California AEI rebate base variables.\n \n Returns:\n Reform: PolicyEngine reform with ca_aei_rebate_base variables\n \"\"\"\n \n class household_fpg(Variable):\n value_type = float\n entity = Household\n label = \"Household's federal poverty guideline\"\n definition_period = YEAR\n unit = USD\n\n def formula(household, period, parameters):\n n = household(\"household_size\", period)\n state_group = household(\"state_group_str\", period)\n p_fpg = parameters(period).gov.hhs.fpg\n p1 = p_fpg.first_person[state_group]\n pn = p_fpg.additional_person[state_group]\n return p1 + pn * (n - 1)\n \n class ca_aei_rebate_base_tax_unit(Variable):\n value_type = float\n entity = TaxUnit\n label = \"California AEI rebate base (tax unit version)\"\n unit = USD\n definition_period = YEAR\n defined_for = StateCode.CA\n\n def formula(tax_unit, period, parameters):\n # Use tax unit's own AGI\n income = tax_unit(\"adjusted_gross_income\", period)\n fpg = tax_unit(\"tax_unit_fpg\", period)\n income_to_fpg_ratio = where(fpg > 0, income / fpg, np.inf)\n\n # Phase-out parameters\n PHASEOUT_START = 1.5 # 150% FPG\n PHASEOUT_END = 1.75 # 175% FPG\n phaseout_width = PHASEOUT_END - PHASEOUT_START\n\n # Phase-out calculation\n excess = max_(income_to_fpg_ratio - PHASEOUT_START, 0)\n phaseout_percentage = min_(1, excess / phaseout_width)\n\n return where(\n income_to_fpg_ratio <= PHASEOUT_END,\n fpg * (1 - phaseout_percentage),\n 0\n )\n\n class ca_aei_rebate_base(Variable):\n value_type = float\n entity = Household\n label = \"California AEI rebate base\"\n unit = USD\n definition_period = YEAR\n\n def formula(household, period, parameters):\n # Sum AGI from all tax units in the household\n income = household.sum(household.members.tax_unit(\"adjusted_gross_income\", period))\n fpg = household(\"household_fpg\", period)\n income_to_fpg_ratio = where(fpg > 0, income / fpg, np.inf)\n\n # Phase-out parameters\n PHASEOUT_START = 1.5 # 150% FPG\n PHASEOUT_END = 1.75 # 175% FPG\n phaseout_width = PHASEOUT_END - PHASEOUT_START\n\n # Phase-out calculation\n excess = max_(income_to_fpg_ratio - PHASEOUT_START, 0)\n phaseout_percentage = min_(1, excess / phaseout_width)\n\n return where(\n income_to_fpg_ratio <= PHASEOUT_END,\n fpg * (1 - phaseout_percentage),\n 0\n )\n\n class AEIReform(Reform):\n def apply(self):\n self.update_variable(household_fpg)\n self.update_variable(ca_aei_rebate_base_tax_unit)\n self.update_variable(ca_aei_rebate_base)\n \n return AEIReform\n\nprint(\"Reform defined successfully\")"
89+
"source": "def create_aei_reform():\n \"\"\"\n Creates a PolicyEngine reform that adds the California AEI rebate base variables.\n \n Returns:\n Reform: PolicyEngine reform with ca_aei_rebate_base variables\n \"\"\"\n \n class household_fpg(Variable):\n value_type = float\n entity = Household\n label = \"Household's federal poverty guideline\"\n definition_period = YEAR\n unit = USD\n\n def formula(household, period, parameters):\n n = household(\"household_size\", period)\n state_group = household(\"state_group_str\", period)\n p_fpg = parameters(period).gov.hhs.fpg\n p1 = p_fpg.first_person[state_group]\n pn = p_fpg.additional_person[state_group]\n return p1 + pn * (n - 1)\n \n class ca_aei_rebate_base_tax_unit(Variable):\n value_type = float\n entity = TaxUnit\n label = \"California AEI rebate base (tax unit version)\"\n unit = USD\n definition_period = YEAR\n defined_for = StateCode.CA\n\n def formula(tax_unit, period, parameters):\n # Use tax unit's own AGI\n income = tax_unit(\"adjusted_gross_income\", period)\n fpg = tax_unit(\"tax_unit_fpg\", period)\n income_to_fpg_ratio = where(fpg > 0, income / fpg, np.inf)\n\n # Phase-out parameters\n PHASEOUT_START = 1.5 # 150% FPG\n PHASEOUT_END = 1.75 # 175% FPG\n phaseout_width = PHASEOUT_END - PHASEOUT_START\n\n # Phase-out calculation\n excess = max_(income_to_fpg_ratio - PHASEOUT_START, 0)\n phaseout_percentage = min_(1, excess / phaseout_width)\n\n return fpg * (1 - phaseout_percentage)\n\n class ca_aei_rebate_base_household(Variable):\n value_type = float\n entity = Household\n label = \"California AEI rebate base (household version)\"\n unit = USD\n definition_period = YEAR\n\n def formula(household, period, parameters):\n # Sum AGI from all tax units in the household\n income = household.sum(household.members.tax_unit(\"adjusted_gross_income\", period))\n fpg = household(\"household_fpg\", period)\n income_to_fpg_ratio = where(fpg > 0, income / fpg, np.inf)\n\n # Phase-out parameters\n PHASEOUT_START = 1.5 # 150% FPG\n PHASEOUT_END = 1.75 # 175% FPG\n phaseout_width = PHASEOUT_END - PHASEOUT_START\n\n # Phase-out calculation\n excess = max_(income_to_fpg_ratio - PHASEOUT_START, 0)\n phaseout_percentage = min_(1, excess / phaseout_width)\n\n return fpg * (1 - phaseout_percentage)\n\n class AEIReform(Reform):\n def apply(self):\n self.update_variable(household_fpg)\n self.update_variable(ca_aei_rebate_base_tax_unit)\n self.update_variable(ca_aei_rebate_base_household)\n \n return AEIReform\n\nprint(\"Reform defined successfully\")"
9090
},
9191
{
9292
"cell_type": "markdown",
@@ -97,7 +97,7 @@
9797
},
9898
{
9999
"cell_type": "code",
100-
"execution_count": 3,
100+
"execution_count": null,
101101
"metadata": {
102102
"execution": {
103103
"iopub.execute_input": "2025-09-15T18:56:46.866675Z",
@@ -106,114 +106,8 @@
106106
"shell.execute_reply": "2025-09-15T18:56:58.429120Z"
107107
}
108108
},
109-
"outputs": [
110-
{
111-
"name": "stdout",
112-
"output_type": "stream",
113-
"text": [
114-
"Loading data and creating simulation...\n"
115-
]
116-
},
117-
{
118-
"name": "stdout",
119-
"output_type": "stream",
120-
"text": [
121-
"Calculating household statistics for 2026...\n"
122-
]
123-
},
124-
{
125-
"name": "stdout",
126-
"output_type": "stream",
127-
"text": [
128-
"Calculating tax_unit statistics for 2026...\n"
129-
]
130-
}
131-
],
132-
"source": [
133-
"def calculate_rebate_base_statistics(sim, unit_type=\"household\", year=2026):\n",
134-
" \"\"\"\n",
135-
" Calculate AEI rebate base program statistics for California households or tax units.\n",
136-
" \n",
137-
" Args:\n",
138-
" sim: Microsimulation object with reform applied\n",
139-
" unit_type: Either \"household\" or \"tax_unit\"\n",
140-
" year: Year to calculate for\n",
141-
" \n",
142-
" Returns:\n",
143-
" Dictionary with rebate base statistics\n",
144-
" \"\"\"\n",
145-
" print(f\"Calculating {unit_type} statistics for {year}...\")\n",
146-
" \n",
147-
" if unit_type == \"household\":\n",
148-
" # Calculate rebate base for all households\n",
149-
" rebate_base = sim.calculate(\"ca_aei_rebate_base\", year)\n",
150-
" \n",
151-
" # Filter for California households only\n",
152-
" household_state = sim.calculate(\"state_code\", year, map_to=\"household\")\n",
153-
" ca_mask = household_state == \"CA\"\n",
154-
" \n",
155-
" # Apply CA filter\n",
156-
" ca_rebate_base = rebate_base[ca_mask]\n",
157-
" total_ca_units = ca_mask.sum()\n",
158-
" \n",
159-
" else: # tax_unit\n",
160-
" # Calculate rebate base for all tax units (defined_for gives 0 for non-CA)\n",
161-
" rebate_base = sim.calculate(\"ca_aei_rebate_base_tax_unit\", year)\n",
162-
" \n",
163-
" # Use calculate_dataframe to get household-level data\n",
164-
" household_df = sim.calculate_dataframe(\n",
165-
" [\"household_id\", \"state_code\"],\n",
166-
" year,\n",
167-
" map_to=\"household\"\n",
168-
" )\n",
169-
" \n",
170-
" # Get tax unit data\n",
171-
" tax_unit_df = sim.calculate_dataframe(\n",
172-
" [\"tax_unit_id\", \"tax_unit_household_id\"],\n",
173-
" year\n",
174-
" )\n",
175-
" \n",
176-
" # Merge to get state for each tax unit\n",
177-
" tax_unit_with_state = tax_unit_df.merge(\n",
178-
" household_df[[\"household_id\", \"state_code\"]],\n",
179-
" left_on=\"tax_unit_household_id\",\n",
180-
" right_on=\"household_id\",\n",
181-
" how=\"left\"\n",
182-
" )\n",
183-
" \n",
184-
" # Create a boolean MicroSeries for CA tax units\n",
185-
" ca_tax_unit_mask = tax_unit_with_state[\"state_code\"] == \"CA\"\n",
186-
" total_ca_units = ca_tax_unit_mask.sum()\n",
187-
" \n",
188-
" # For tax units, we use all rebates (defined_for already filters to CA)\n",
189-
" ca_rebate_base = rebate_base\n",
190-
" \n",
191-
" # Calculate statistics (MicroSeries already contain weights)\n",
192-
" units_with_rebate = (ca_rebate_base > 0).sum()\n",
193-
" total_rebate_base = ca_rebate_base.sum()\n",
194-
" average_rebate_base = ca_rebate_base[ca_rebate_base > 0].mean() if units_with_rebate > 0 else 0\n",
195-
" \n",
196-
" return {\n",
197-
" \"unit_type\": unit_type,\n",
198-
" \"total_ca_units\": total_ca_units,\n",
199-
" \"units_with_rebate\": units_with_rebate,\n",
200-
" \"rebate_percentage\": units_with_rebate / total_ca_units,\n",
201-
" \"average_rebate_base\": average_rebate_base,\n",
202-
" \"total_rebate_base\": total_rebate_base,\n",
203-
" }\n",
204-
"\n",
205-
"# Create simulation once\n",
206-
"print(\"Loading data and creating simulation...\")\n",
207-
"reform = create_aei_reform()\n",
208-
"sim = Microsimulation(\n",
209-
" dataset=\"hf://policyengine/policyengine-us-data/pooled_3_year_cps_2023.h5\",\n",
210-
" reform=reform\n",
211-
")\n",
212-
"\n",
213-
"# Calculate both household and tax unit results using the same simulation\n",
214-
"household_results = calculate_rebate_base_statistics(sim, \"household\", SIMULATION_YEAR)\n",
215-
"tax_unit_results = calculate_rebate_base_statistics(sim, \"tax_unit\", SIMULATION_YEAR)"
216-
]
109+
"outputs": [],
110+
"source": "def calculate_rebate_base_statistics(sim, unit_type=\"household\", year=2026):\n \"\"\"\n Calculate AEI rebate base program statistics for California households or tax units.\n \n Args:\n sim: Microsimulation object with reform applied\n unit_type: Either \"household\" or \"tax_unit\"\n year: Year to calculate for\n \n Returns:\n Dictionary with rebate base statistics\n \"\"\"\n print(f\"Calculating {unit_type} statistics for {year}...\")\n \n if unit_type == \"household\":\n # Calculate rebate base for all households\n rebate_base = sim.calculate(\"ca_aei_rebate_base_household\", year)\n \n # Filter for California households only\n household_state = sim.calculate(\"state_code\", year, map_to=\"household\")\n ca_mask = household_state == \"CA\"\n \n # Apply CA filter\n ca_rebate_base = rebate_base[ca_mask]\n total_ca_units = ca_mask.sum()\n \n else: # tax_unit\n # Calculate rebate base for all tax units (defined_for gives 0 for non-CA)\n rebate_base = sim.calculate(\"ca_aei_rebate_base_tax_unit\", year)\n \n # Use calculate_dataframe to get household-level data\n household_df = sim.calculate_dataframe(\n [\"household_id\", \"state_code\"],\n year,\n map_to=\"household\"\n )\n \n # Get tax unit data\n tax_unit_df = sim.calculate_dataframe(\n [\"tax_unit_id\", \"tax_unit_household_id\"],\n year\n )\n \n # Merge to get state for each tax unit\n tax_unit_with_state = tax_unit_df.merge(\n household_df[[\"household_id\", \"state_code\"]],\n left_on=\"tax_unit_household_id\",\n right_on=\"household_id\",\n how=\"left\"\n )\n \n # Create a boolean MicroSeries for CA tax units\n ca_tax_unit_mask = tax_unit_with_state[\"state_code\"] == \"CA\"\n total_ca_units = ca_tax_unit_mask.sum()\n \n # For tax units, we use all rebates (defined_for already filters to CA)\n ca_rebate_base = rebate_base\n \n # Calculate statistics (MicroSeries already contain weights)\n units_with_rebate = (ca_rebate_base > 0).sum()\n total_rebate_base = ca_rebate_base.sum()\n average_rebate_base = ca_rebate_base[ca_rebate_base > 0].mean() if units_with_rebate > 0 else 0\n \n return {\n \"unit_type\": unit_type,\n \"total_ca_units\": total_ca_units,\n \"units_with_rebate\": units_with_rebate,\n \"rebate_percentage\": units_with_rebate / total_ca_units,\n \"average_rebate_base\": average_rebate_base,\n \"total_rebate_base\": total_rebate_base,\n }\n\n# Create simulation once\nprint(\"Loading data and creating simulation...\")\nreform = create_aei_reform()\nsim = Microsimulation(\n dataset=\"hf://policyengine/policyengine-us-data/pooled_3_year_cps_2023.h5\",\n reform=reform\n)\n\n# Calculate both household and tax unit results using the same simulation\nhousehold_results = calculate_rebate_base_statistics(sim, \"household\", SIMULATION_YEAR)\ntax_unit_results = calculate_rebate_base_statistics(sim, \"tax_unit\", SIMULATION_YEAR)"
217111
},
218112
{
219113
"cell_type": "markdown",

0 commit comments

Comments
 (0)