Skip to content

Commit 8a76dea

Browse files
MaxGhenisclaude
andauthored
Align state AGI-band convention with main SOI loop ([lower, upper)) (#775)
`_add_state_agi_metric_columns` used `(agi > lower) & (agi <= upper)` (left-exclusive, right-inclusive) while the main SOI loop in `build_loss_matrix` at line 425 uses `(agi >= lower) & (agi < upper)` (left-inclusive, right-exclusive). Both loops read from the same SOI CSV; the SOI data is published on the half-open `[lower, upper)` convention, so the state-band loop was misclassifying records that sit exactly on bucket boundaries. Switch to the `[lower, upper)` convention for consistency with both the main SOI loop and the underlying data. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 175b96d commit 8a76dea

2 files changed

Lines changed: 5 additions & 1 deletion

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use the [lower, upper) AGI-band boundary convention in the state AGI metric loop, matching the main SOI loop in build_loss_matrix.

policyengine_us_data/utils/loss.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1033,7 +1033,10 @@ def _add_agi_metric_columns(
10331033
band = get_agi_band_label(lower, upper)
10341034

10351035
in_state = state == r.GEO_NAME
1036-
in_band = (agi > lower) & (agi <= upper)
1036+
# Use the same [lower, upper) boundary convention as the main SOI
1037+
# loop in build_loss_matrix() (the SOI targets use half-open bands
1038+
# starting at the lower bound).
1039+
in_band = (agi >= lower) & (agi < upper)
10371040

10381041
if r.IS_COUNT:
10391042
metric = (in_state & in_band & (agi > 0)).astype(float)

0 commit comments

Comments
 (0)