processing.weighting.controls
Weighting control definitions and registry.
Provides the CONTROLS registry mapping control names to
ControlTarget instances, plus
household-level and person-level concrete control classes that define
pums_expr / survey_expr recoding logic.
processing.weighting.controls.base
Base class and helpers for weighting controls.
Contains ControlLevel, ControlTarget base class, and shared
expression helpers used by the household and person control subclasses.
MAX_CROSSTAB_CELLS
module-attribute
MAX_CROSSTAB_CELLS = 500
INFO_CROSSTAB_CELLS
module-attribute
INFO_CROSSTAB_CELLS = 100
MAX_TOTAL_CATEGORIES
module-attribute
MAX_TOTAL_CATEGORIES = 200
INFO_TOTAL_CATEGORIES
module-attribute
INFO_TOTAL_CATEGORIES = 100
ControlLevel
Whether a control is at the household or person level.
HOUSEHOLD
class-attribute
instance-attribute
HOUSEHOLD = 'household'
PERSON
class-attribute
instance-attribute
PERSON = 'person'
ControlTarget
Base class for a single weighting control.
Subclasses set class attributes and override survey_expr /
pums_expr to return native Polars expressions.
Attributes:
| Name | Type | Description |
|---|---|---|
name |
str
|
Registry key, e.g. |
level |
ControlLevel
|
|
description |
str
|
Human-readable label. |
categories |
type[Enum]
|
|
survey_fields |
tuple[str, ...]
|
Canonical survey column names (metadata). |
pums_fields |
tuple[str, ...]
|
PUMS column names (metadata). |
name
instance-attribute
name: str
description
instance-attribute
description: str
categories
instance-attribute
categories: type[Enum]
survey_fields
instance-attribute
survey_fields: tuple[str, ...]
pums_fields
instance-attribute
pums_fields: tuple[str, ...]
structural
class-attribute
instance-attribute
structural: bool = False
valid_members
property
valid_members: list[tuple[int, str]]
(value, name) for each non-sentinel output category.
survey_expr
survey_expr() -> pl.Expr
Polars expression mapping survey columns → control int (Int16).
pums_expr
pums_expr() -> pl.Expr
Polars expression mapping PUMS columns → control int (Int16).
CrosstabControlTarget
Base class for N-dimensional cross-tabulated weighting control.
Cross-tabs are built from the cartesian product of effective dimension members — after any per-dimension merges have been applied. Merges are resolved at registration time so the enum, expression, and validation all reflect the actual cell count.
Subclasses set these additional attributes:
dim_controls: tuple of ControlTarget instances to cross-tabulatecategories: IntEnum generated at registration from effective dimsdim_value_groups: per-dimension list of (name, values) tuples describing the effective members (may include merged groups)
The survey_expr() / pums_expr() methods are implemented
automatically to map dimension column values to composite indices.
dim_value_groups
instance-attribute
dim_value_groups: list[list[tuple[str, list[int]]]]
survey_expr
survey_expr() -> pl.Expr
Combine dimension control columns into composite key.
Requires dimension control columns to already exist in the DataFrame (recoded earlier in the control loop). Returns sequential integer (0, 1, 2, ...) corresponding to position in the cartesian product of dimension categories.
pums_expr
pums_expr() -> pl.Expr
Combine dimension control columns into composite key.
Requires dimension control columns to already exist in the DataFrame (recoded earlier in the control loop). Uses same mapping as survey_expr().
identity_expr
identity_expr(col: str, categories: type[Enum]) -> pl.Expr
Pass-through valid values, null for sentinels or unknown.
Basically, we use the canonical enum directly, just map sentinels to null.
breakpoint_expr
breakpoint_expr(col: str, categories: type[Enum]) -> pl.Expr
Build a when/then chain from a LabeledEnum with BREAKPOINTS.
Zips categories.BREAKPOINTS with the non-sentinel members so that
each breakpoint maps col < bp → the corresponding member value,
with the final member as the otherwise catch-all.
processing.weighting.controls.enums
Custom IntEnum categories for weighting controls.
These define the output bins for the 8 collapsing controls where the
canonical survey granularity is reduced to fewer bins for weighting. The
5 identity controls (income, education, race, ethnicity, age) reuse
canonical LabeledEnum directly and are not duplicated here.
HHSizeCategory
Household size bins (1-9, 10+).
SIZE_1
class-attribute
instance-attribute
SIZE_1 = 1
SIZE_2
class-attribute
instance-attribute
SIZE_2 = 2
SIZE_3
class-attribute
instance-attribute
SIZE_3 = 3
SIZE_4
class-attribute
instance-attribute
SIZE_4 = 4
SIZE_5
class-attribute
instance-attribute
SIZE_5 = 5
SIZE_6
class-attribute
instance-attribute
SIZE_6 = 6
SIZE_7
class-attribute
instance-attribute
SIZE_7 = 7
SIZE_8
class-attribute
instance-attribute
SIZE_8 = 8
SIZE_9
class-attribute
instance-attribute
SIZE_9 = 9
SIZE_10_PLUS
class-attribute
instance-attribute
SIZE_10_PLUS = 10
HHWorkersCategory
Number of workers in household (0-4, 5+).
WORKERS_0
class-attribute
instance-attribute
WORKERS_0 = 0
WORKERS_1
class-attribute
instance-attribute
WORKERS_1 = 1
WORKERS_2
class-attribute
instance-attribute
WORKERS_2 = 2
WORKERS_3
class-attribute
instance-attribute
WORKERS_3 = 3
WORKERS_4
class-attribute
instance-attribute
WORKERS_4 = 4
WORKERS_5_PLUS
class-attribute
instance-attribute
WORKERS_5_PLUS = 5
HHVehiclesCategory
Vehicles available to household (0-5, 6+).
VEH_0
class-attribute
instance-attribute
VEH_0 = 0
VEH_1
class-attribute
instance-attribute
VEH_1 = 1
VEH_2
class-attribute
instance-attribute
VEH_2 = 2
VEH_3
class-attribute
instance-attribute
VEH_3 = 3
VEH_4
class-attribute
instance-attribute
VEH_4 = 4
VEH_5
class-attribute
instance-attribute
VEH_5 = 5
VEH_6_PLUS
class-attribute
instance-attribute
VEH_6_PLUS = 6
HHChildrenCategory
Number of children in household (0-4, 5+).
CHILDREN_0
class-attribute
instance-attribute
CHILDREN_0 = 0
CHILDREN_1
class-attribute
instance-attribute
CHILDREN_1 = 1
CHILDREN_2
class-attribute
instance-attribute
CHILDREN_2 = 2
CHILDREN_3
class-attribute
instance-attribute
CHILDREN_3 = 3
CHILDREN_4
class-attribute
instance-attribute
CHILDREN_4 = 4
CHILDREN_5_PLUS
class-attribute
instance-attribute
CHILDREN_5_PLUS = 5
GenderCategory
Gender bins for weighting (male / female / other).
PUMS only has binary SEX.
MALE
class-attribute
instance-attribute
MALE = 1
FEMALE
class-attribute
instance-attribute
FEMALE = 2
EmploymentCategory
Employment status for weighting (full / part / not employed).
EMPLOYED_FULL
class-attribute
instance-attribute
EMPLOYED_FULL = 1
EMPLOYED_PART
class-attribute
instance-attribute
EMPLOYED_PART = 2
NOT_EMPLOYED
class-attribute
instance-attribute
NOT_EMPLOYED = 3
CommuteModeCategory
Commute mode for weighting.
NA
class-attribute
instance-attribute
NA = 0
MOSTLY_REMOTE
class-attribute
instance-attribute
MOSTLY_REMOTE = 1
DRIVE_ALONE
class-attribute
instance-attribute
DRIVE_ALONE = 2
CARPOOL
class-attribute
instance-attribute
CARPOOL = 3
TRANSIT
class-attribute
instance-attribute
TRANSIT = 4
WALK
class-attribute
instance-attribute
WALK = 5
BIKE
class-attribute
instance-attribute
BIKE = 6
OTHER
class-attribute
instance-attribute
OTHER = 7
StudentCategory
Student status (not student / K-12 / college).
NOT_STUDENT
class-attribute
instance-attribute
NOT_STUDENT = 0
STUDENT_K12
class-attribute
instance-attribute
STUDENT_K12 = 1
STUDENT_COLLEGE
class-attribute
instance-attribute
STUDENT_COLLEGE = 2
TotalCategory
Single-category enum for h_total / p_total structural controls.
TOTAL
class-attribute
instance-attribute
TOTAL = 1
make_crosstab_enum
make_crosstab_enum(
name: str, dim_value_groups: list[list[tuple[str, list[int]]]]
) -> type[IntEnum]
Create an IntEnum for N-dimensional cross-tabulated control.
Generates a cartesian product of effective dimension members (which may include merged groups). Each composite member is assigned a sequential integer value (0, 1, 2, ...).
Parameters
name : str
Name for the generated IntEnum class.
dim_value_groups : list[list[tuple[str, list[int]]]]
Per-dimension list of (member_name, original_values) tuples.
Single-value entries are unmerged; multi-value entries are merged
groups.
Returns:
type[IntEnum] New IntEnum with composite members from cartesian product.
Examples:
groups = [ ... [("SIZE_1", [1]), ("SIZE_2", [2]), ("SIZE_3_PLUS", [3,4,5])], ... [("INCOME_UNDER_100", [1,2,3,4]), ("INCOME_100TO200", [5])], ... ] SizeIncomeCategory = make_crosstab_enum("SizeIncomeCategory", groups) len(SizeIncomeCategory) # 3 x 2 = 6 6
processing.weighting.controls.household
Household-level weighting controls.
Each class maps raw survey / PUMS values into coarser category ints for household-level weighting targets.
All survey_expr / pums_expr overrides implement the interface
documented in ControlTarget
— individual method docstrings are omitted for brevity (ruff noqa: D102).
HHSizeControl
Household size (1-10+).
name
class-attribute
instance-attribute
name = 'h_size'
description
class-attribute
instance-attribute
description = 'Household size'
survey_fields
class-attribute
instance-attribute
survey_fields = ('_n_persons',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('NP',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
HHIncomeControl
Household income (canonical IncomeBroad bins).
name
class-attribute
instance-attribute
name = 'h_income'
description
class-attribute
instance-attribute
description = 'Household income'
survey_fields
class-attribute
instance-attribute
survey_fields = ('income_bin',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('HINCP',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
HHWorkersControl
Number of workers in household (0-5+).
name
class-attribute
instance-attribute
name = 'h_workers'
description
class-attribute
instance-attribute
description = 'Workers in household'
survey_fields
class-attribute
instance-attribute
survey_fields = ('_n_workers',)
pums_fields
class-attribute
instance-attribute
pums_fields = ()
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
HHVehiclesControl
Vehicles in household (0-6+).
name
class-attribute
instance-attribute
name = 'h_vehicles'
description
class-attribute
instance-attribute
description = 'Vehicles in household'
survey_fields
class-attribute
instance-attribute
survey_fields = ('num_vehicles',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('VEH',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
HHChildrenControl
Children in household (0-5+).
name
class-attribute
instance-attribute
name = 'h_children'
description
class-attribute
instance-attribute
description = 'Children in household'
survey_fields
class-attribute
instance-attribute
survey_fields = ('_n_children',)
pums_fields
class-attribute
instance-attribute
pums_fields = ()
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
HHTotalControl
Structural control: total households (incidence = 1 per HH).
name
class-attribute
instance-attribute
name = 'h_total'
description
class-attribute
instance-attribute
description = 'Total households'
survey_fields
class-attribute
instance-attribute
survey_fields = ()
pums_fields
class-attribute
instance-attribute
pums_fields = ()
structural
class-attribute
instance-attribute
structural = True
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
processing.weighting.controls.person
Person-level weighting controls.
Each class maps raw survey / PUMS values into coarser category ints for person-level weighting targets.
All survey_expr / pums_expr overrides implement the interface
documented in ControlTarget
— individual method docstrings are omitted for brevity (ruff noqa: D102) because the base class
fully documents the expected behavior and error handling.
GenderControl
Gender (male / female).
name
class-attribute
instance-attribute
name = 'p_gender'
description
class-attribute
instance-attribute
description = 'Gender'
survey_fields
class-attribute
instance-attribute
survey_fields = ('gender',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('SEX',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
EmploymentControl
Employment status (full-time / part-time / not employed).
name
class-attribute
instance-attribute
name = 'p_employment'
description
class-attribute
instance-attribute
description = 'Employment status'
survey_fields
class-attribute
instance-attribute
survey_fields = ('employment',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('ESR', 'WKHP')
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
ESR + WKHP → employment category (WKHP < 35 = part-time).
ESR is null for persons under 16 — they are coded as not employed.
CommuteModeControl
Commute mode (drive, carpool, transit, bike, walk, mostly_remote, other, N/A).
Survey side: Uses a combination of job_type, telework_freq, and
commute_freq to identify mostly-remote workers — those whose telework
frequency exceeds their commute frequency. For all other workers the
observed work_mode determines the category.
PUMS side: JWTRNS=11 ("Worked at home") maps to MOSTLY_REMOTE.
This is the closest analog — the PUMS question asks about the usual
mode to work, so respondents who mostly remote-work select this.
name
class-attribute
instance-attribute
name = 'p_commute_mode'
description
class-attribute
instance-attribute
description = 'Commute mode'
survey_fields
class-attribute
instance-attribute
survey_fields = (
"work_mode",
"job_type",
"telework_freq",
"commute_freq",
)
pums_fields
class-attribute
instance-attribute
pums_fields = ('JWTRNS', 'JWRIP')
survey_expr
survey_expr() -> pl.Expr
Classify survey persons into commute-mode categories.
Mostly-remote detection (checked first):
1. job_type == 3 (WFH always)
2. telework 5+ days/week AND rarely/never commutes
3. Telework ratio >60%: commute_freq > telework_freq + 1
for weekly-or-more frequencies on both sides
Everyone else falls through to the work_mode mapping.
pums_expr
pums_expr() -> pl.Expr
JWRIP >= 2 refines drive-alone to carpool.
StudentControl
Student status (K-12 / college / not a student).
Classification priority
- Explicit non-student (
student == NONSTUDENT) → NOT_STUDENT - Known K-12 school type (preschool thru high school) → K12
- Known college school type → COLLEGE
- Childcare / at-home (not school in the Census sense) → NOT_STUDENT
- Age-based fallback when both student & school_type are missing: school-age children (5-17) → K12, everyone else → NOT_STUDENT
- Active student with missing school_type → COLLEGE (adult default)
The student field is only collected for persons age 16+ in the
survey instrument; younger children have student = 995 (MISSING)
but typically have a valid school_type, so school_type is checked
before discarding missing students.
name
class-attribute
instance-attribute
name = 'p_student'
description
class-attribute
instance-attribute
description = 'Student status'
survey_fields
class-attribute
instance-attribute
survey_fields = ('student', 'school_type', 'age')
pums_fields
class-attribute
instance-attribute
pums_fields = ('SCHG',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
EducationControl
Education attainment (canonical Education enum).
name
class-attribute
instance-attribute
name = 'p_education'
description
class-attribute
instance-attribute
description = 'Education attainment'
survey_fields
class-attribute
instance-attribute
survey_fields = ('education',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('SCHL',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
RaceControl
Race (canonical Race enum).
name
class-attribute
instance-attribute
name = 'p_race'
description
class-attribute
instance-attribute
description = 'Race'
survey_fields
class-attribute
instance-attribute
survey_fields = ('race',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('RAC1P',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
EthnicityControl
Hispanic/Latino ethnicity (canonical Ethnicity enum).
name
class-attribute
instance-attribute
name = 'p_ethnicity'
description
class-attribute
instance-attribute
description = 'Hispanic/Latino ethnicity'
survey_fields
class-attribute
instance-attribute
survey_fields = ('ethnicity',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('HISP',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
AgeControl
Age (canonical AgeCategory breakpoints).
name
class-attribute
instance-attribute
name = 'p_age'
description
class-attribute
instance-attribute
description = 'Age'
survey_fields
class-attribute
instance-attribute
survey_fields = ('age',)
pums_fields
class-attribute
instance-attribute
pums_fields = ('AGEP',)
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
PersonTotalControl
Structural control: total persons (incidence = 1 per person).
When aggregated to the seed table (one row per household), the incidence column becomes the count of persons in the household — effectively the non-top-coded household size.
name
class-attribute
instance-attribute
name = 'p_total'
description
class-attribute
instance-attribute
description = 'Total persons'
survey_fields
class-attribute
instance-attribute
survey_fields = ()
pums_fields
class-attribute
instance-attribute
pums_fields = ()
structural
class-attribute
instance-attribute
structural = True
survey_expr
survey_expr() -> pl.Expr
pums_expr
pums_expr() -> pl.Expr
processing.weighting.controls.registry
Control registry and resolution helpers.
The CONTROLS dict is the single lookup table mapping control names
to :class:ControlTarget instances. resolve_targets and
pums_variables provide the main query API used by the rest of the
weighting pipeline.
Dynamic cross-tab creation:
register_crosstab creates a CrosstabControlTarget instance at runtime
from dimension control names, allowing cross-tabs to be defined in YAML
config without requiring Python class definitions.
CONTROLS
module-attribute
CONTROLS: dict[str, ControlTarget] = {
(t.name): t
for t in [
HHTotalControl(),
HHSizeControl(),
HHIncomeControl(),
HHWorkersControl(),
HHVehiclesControl(),
HHChildrenControl(),
PersonTotalControl(),
GenderControl(),
EmploymentControl(),
CommuteModeControl(),
StudentControl(),
EducationControl(),
RaceControl(),
EthnicityControl(),
AgeControl(),
]
}
resolve_targets
resolve_targets(
targets: list[str], level: ControlLevel | None = None
) -> list[ControlTarget]
Return ControlTarget objects for targets, optionally filtered.
pums_variables
pums_variables(level: ControlLevel) -> set[str]
PUMS variable names needed for all controls at level.
register_crosstab
register_crosstab(
name: str,
dimension_names: list[str],
merges: dict[str, dict[str, list[str]]] | None = None,
) -> ControlTarget
Dynamically create and register a crosstab control.
Merges are applied at registration time so the enum and expression reflect the effective (post-merge) cell count.
Parameters
name : str
Name for the cross-tab control (will be registered in CONTROLS).
dimension_names : list[str]
Names of dimension controls to cross-tabulate (must exist in CONTROLS).
merges : dict | None
Optional per-dimension merge specs. Keys are dimension control
names, values are {merged_label: [source_member_names]}.
Source names must match the dimension enum member names
(case-insensitive). Unmentioned members are kept as-is.
Returns:
ControlTarget The newly created and registered CrosstabControlTarget instance.
Examples:
xtab = register_crosstab( ... "h_size_by_income", ... ["h_size", "h_income"], ... merges={ ... "h_size": {"size_3_plus": ["size_3", "size_4", "size_5"]}, ... "h_income": {"income_under_100": ["income_under25", "income_25to50"]}, ... }, ... )
register_crosstabs_from_config
register_crosstabs_from_config(controls: list[dict]) -> None
Register any cross-tab controls defined in config before parsing.
Scans the controls list for entries with a dimensions key and
dynamically creates CrosstabControlTarget instances. If a merges
key is present, those per-dimension merges are applied at registration
time so the enum reflects the effective cell count.
Parameters
controls : list[dict] Raw control definitions from YAML config.