PolicyEngine / PolicyEngine/microcosm
Preserve single-year ages 80–84 by using ACS AGEP on the national spine
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 4
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 94
Description
Problem
The pinned national Build P release (populace-us-2024-buildp-sparse-rmloss100-cae8640-20260728T011454Z) inherits its age input from the CPS ASEC public-use A_AGE field.
CPS ASEC does not publish literal single-year ages across the upper tail:
A_AGE = 80means ages 80–84.A_AGE = 85means ages 85+.
Microcosm currently copies that public-use code directly in packages/populace-build/src/populace/build/us_runtime/cps_carried.py:
_fill_missing(person, "age", _source(person, "A_AGE"))
Inspection of the published HDF5 confirms that A_AGE == age for these records and that the support has no values 81–84: 3,222 physical rows use code 80, zero use 81–84, and 2,678 use code 85.
This is inherited from the Census CPS ASEC categorization rather than being a new Microcosm recode. PR #182 introduced the direct carry, but the grouped semantics are not represented in the resulting PolicyEngine age values. The Census definition is in the 2023 ASEC data dictionary.
Why it matters
PolicyEngine receives these category codes as though they were literal ages. Consequently:
- people actually aged 81–84 are evaluated as age 80;
- everyone aged 85+ is evaluated as age 85;
- single-year demographic validation for ages 80–84 is impossible from this released national dataset;
- policies whose rules vary within either range can be evaluated against the wrong literal age.
Our Chronicle evaluation initially exposed this by attempting five separate single-year comparisons. The corrected evaluation now:
- compares Microcosm code 80 once with the sum of Chronicle ages 80–84: benchmark 7,416,564, estimate 7,304,087.5, capped relative error 1.52%;
- compares Microcosm code 85 with Chronicle age 85+: benchmark 6,858,824, estimate 6,434,691, capped relative error 6.18%;
- preserves traceability to all five 80–84 facts while scoring that grouped measurement only once.
ACS AGEP solves this for ages 80–84
The ACS multispine path added by PR #528 already maps ACS PUMS AGEP to age with an identity transformation in acs_inputs.py.
Unlike CPS A_AGE, ACS AGEP contains single-year ages 80, 81, 82, 83, and 84. It remains single-year through age 98 and is top-coded only at 99, as documented in the ACS PUMS data dictionary. An ACS-based national spine can therefore preserve the upper-age detail without inferring a split from the validation targets.
Proposed work
- Make ACS
AGEPauthoritative foragein the national multispine build. - Add a release gate asserting that ages 80–84 each have positive support and that a grouped CPS category is not being treated as a literal age.
- Validate ages 80–84 against the corresponding Chronicle/Census single-year projections.
- Document the remaining ACS age-99 topcode.
- Until the ACS national spine is used, document the current Build P semantics explicitly as 80 = ages 80–84 and 85 = ages 85+.
Acceptance criteria
- The published national HDF5 has distinct support at ages 80, 81, 82, 83, and 84.
- The
agelineage identifies ACSAGEP, rather than grouped CPSA_AGE, for those rows. - Single-year ages 80–84 can be validated without synthetic disaggregation.
- The treatment of the uppermost age category is explicit for every released lineage.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in packages/populace-build/src/populace/build/us_runtime/cps_carried.py and review the ACS age mapping in acs_inputs.py. Check the published HDF5 support and existing release or validation entry points before deciding how the ACS source becomes authoritative. Done means ages 80–84 have distinct support, lineage identifies ACS AGEP, validation covers those ages, and age-99/top-code semantics are documented.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- data-engineering
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100