Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
baf2a24
Align SPM threshold recalculation
MaxGhenis Apr 7, 2026
418d73c
Split housing benchmarks by Census and HUD concepts
MaxGhenis Apr 7, 2026
c71e53a
Stabilize clone-half SPM thresholds and weight priors
MaxGhenis Apr 8, 2026
84e4259
Format clone-half threshold fixes
MaxGhenis Apr 8, 2026
289bbc7
Format SPM benchmark and calibration files
MaxGhenis Apr 8, 2026
9b72228
Add changelog fragment for clone-half SPM fixes
MaxGhenis Apr 8, 2026
1151faa
Retrigger PR checks
MaxGhenis Apr 8, 2026
9c01bc7
Retrigger PR checks after cancel
MaxGhenis Apr 8, 2026
893d6ad
Merge upstream main into codex/spm-threshold-align-data
MaxGhenis Apr 8, 2026
0caed79
Fix Towncrier fragment layout
MaxGhenis Apr 8, 2026
67d2af7
Add clone origin diagnostics for ECPS
MaxGhenis Apr 8, 2026
b06a2bd
Add changelog fragment for clone diagnostics
MaxGhenis Apr 8, 2026
f908809
Format clone diagnostics files
MaxGhenis Apr 8, 2026
98a4e47
Tighten clone prior and tenure validation
MaxGhenis Apr 8, 2026
a855384
Harden clone diagnostics reporting
MaxGhenis Apr 8, 2026
aed202a
Fix local-area calibration imports and takeup args
MaxGhenis Apr 9, 2026
e2ae174
Harden housing target test stub
MaxGhenis Apr 9, 2026
dacb1f6
Harden clone diagnostics refresh
MaxGhenis Apr 9, 2026
f5750e3
Trigger PR checks
MaxGhenis Apr 9, 2026
f9162bd
Use Census childcare capping formula
MaxGhenis Apr 9, 2026
fe77557
Add childcare formula changelog fragment
MaxGhenis Apr 9, 2026
1f518c9
Upload clone diagnostics and preserve clone flags
MaxGhenis Apr 9, 2026
2bce19a
Merge remote-tracking branch 'upstream/main' into codex/spm-threshold…
MaxGhenis Apr 9, 2026
dd75f1d
Populate childcare formula inputs from CPS
MaxGhenis Apr 9, 2026
18f8ebd
Carry CPS partner input for SPM childcare
MaxGhenis Apr 9, 2026
e5a488e
Format CPS PERRP mapping
MaxGhenis Apr 9, 2026
1a0678a
Handle period keys in small ECPS clone flags
MaxGhenis Apr 9, 2026
17e77b3
Use valid year in housing target test
MaxGhenis Apr 9, 2026
3a1d36b
Merge branch 'codex/spm-threshold-align-data' into codex/spm-all-fixe…
MaxGhenis Apr 9, 2026
1b48cd3
Merge clone diagnostics into all-fixes build
MaxGhenis Apr 9, 2026
2ce83f6
Merge childcare formula into all-fixes build
MaxGhenis Apr 9, 2026
09a42f4
Use modeled Medicare Part B inputs and targets
MaxGhenis Apr 10, 2026
8f8eb8e
Fix Medicare Part B changelog fragment
MaxGhenis Apr 10, 2026
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
1 change: 1 addition & 0 deletions changelog.d/702.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Aligned clone-half enhanced CPS generation with the modeled SPM pipeline by rebuilding cloned SPM thresholds deterministically and keeping zero-weight synthetic households near zero in sparse reweighting priors.
1 change: 1 addition & 0 deletions changelog.d/703.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added explicit clone-origin flags to extended/enhanced CPS datasets and saved ECPS clone diagnostics for clone weight share, modeled-only-poor share, and extreme childcare/tax checks.
1 change: 1 addition & 0 deletions changelog.d/705.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Use Census work-and-childcare capping inputs for clone-half SPM childcare expenses instead of donor capping shares.
1 change: 1 addition & 0 deletions changelog.d/713.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Modeled Medicare Part B premiums from enrollment and premium schedules, netted a cycle-free MSP standard-premium offset, and documented the national Part B calibration target as an approximate beneficiary-paid out-of-pocket benchmark rather than gross CMS premium income.
44 changes: 31 additions & 13 deletions policyengine_us_data/calibration/calibration_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@
import numpy as np
import pandas as pd

from spm_calculator import SPMCalculator, spm_equivalence_scale
from spm_calculator.geoadj import calculate_geoadj_from_rent

from policyengine_us_data.utils.spm import TENURE_CODE_MAP
from policyengine_us_data.utils.spm import (
TENURE_CODE_MAP,
calculate_geoadj_from_rent,
get_spm_reference_thresholds,
spm_equivalence_scale,
)
from policyengine_us.variables.household.demographic.geographic.state_name import (
StateName,
)
Expand Down Expand Up @@ -491,6 +493,7 @@ def get_cd_index_mapping(db_uri: str = None):
tuple: (cd_to_index dict, index_to_cd dict, cds_ordered list)
"""
from sqlalchemy import create_engine, text
from pathlib import Path
from policyengine_us_data.storage import STORAGE_FOLDER

if db_uri is None:
Expand Down Expand Up @@ -531,7 +534,7 @@ def load_geo_labels(path) -> List[str]:

def load_cd_geoadj_values(
cds_to_calibrate: List[str],
) -> Dict[str, float]:
) -> Dict[str, Dict[str, float]]:
"""
Load geographic adjustment factors from rent data CSV.
Uses median 2BR rent by CD vs national median to compute geoadj.
Expand All @@ -550,19 +553,30 @@ def load_cd_geoadj_values(
# Build lookup from rent data
rent_lookup = {}
for _, row in rent_df.iterrows():
geoadj = calculate_geoadj_from_rent(
local_rent=row["median_2br_rent"],
national_rent=row["national_median_2br_rent"],
)
rent_lookup[row["cd_geoid"]] = geoadj
rent_lookup[row["cd_geoid"]] = {
tenure: calculate_geoadj_from_rent(
local_rent=row["median_2br_rent"],
national_rent=row["national_median_2br_rent"],
tenure=tenure,
)
for tenure in (
"owner_with_mortgage",
"owner_without_mortgage",
"renter",
)
}

geoadj_dict = {}
for cd in cds_to_calibrate:
if cd in rent_lookup:
geoadj_dict[cd] = rent_lookup[cd]
else:
print(f"Warning: No rent data for CD {cd}, using geoadj=1.0")
geoadj_dict[cd] = 1.0
geoadj_dict[cd] = {
"owner_with_mortgage": 1.0,
"owner_without_mortgage": 1.0,
"renter": 1.0,
}

return geoadj_dict

Expand Down Expand Up @@ -593,6 +607,11 @@ def calculate_spm_thresholds_vectorized(
Returns:
Float32 array of SPM thresholds, one per SPM unit.
"""
person_ages = np.asarray(person_ages)
person_spm_unit_ids = np.asarray(person_spm_unit_ids)
spm_unit_tenure_types = np.asarray(spm_unit_tenure_types)
spm_unit_geoadj = np.asarray(spm_unit_geoadj, dtype=np.float64)

n_units = len(spm_unit_tenure_types)

# Count adults and children per SPM unit
Expand All @@ -614,8 +633,7 @@ def calculate_spm_thresholds_vectorized(
tenure_codes[mask] = code

# Look up base thresholds
calc = SPMCalculator(year=year)
base_thresholds = calc.get_base_thresholds()
base_thresholds = get_spm_reference_thresholds(year)

thresholds = np.zeros(n_units, dtype=np.float32)
for i in range(n_units):
Expand Down
Loading
Loading