diff --git a/changelog.d/wic-postpartum.fixed.md b/changelog.d/wic-postpartum.fixed.md new file mode 100644 index 00000000000..dbd9e51f96b --- /dev/null +++ b/changelog.d/wic-postpartum.fixed.md @@ -0,0 +1 @@ +Make only one mother per infant WIC postpartum or breastfeeding, so a grandmother living with her grandchild no longer qualifies. diff --git a/policyengine_us/tests/policy/baseline/gov/usda/wic/wic_category.yaml b/policyengine_us/tests/policy/baseline/gov/usda/wic/wic_category.yaml index c22fe7aebfa..1b185be2360 100644 --- a/policyengine_us/tests/policy/baseline/gov/usda/wic/wic_category.yaml +++ b/policyengine_us/tests/policy/baseline/gov/usda/wic/wic_category.yaml @@ -119,3 +119,413 @@ age: 5 output: wic_category: NONE + +# 7 CFR 246.2: postpartum women are "women up to six months after termination +# of pregnancy" and breastfeeding women are "women up to one year postpartum +# who are breastfeeding their infants", so an infant makes only its own mother +# postpartum or breastfeeding, not a grandmother who has her own child at home. +- name: Three generations in separate tax units, only the infant's mother is postpartum + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + grandmother_tax_unit: + members: [grandmother] + mother_tax_unit: + members: [mother, infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, POSTPARTUM, INFANT] + +- name: Three generations in one tax unit, only the youngest mother is postpartum + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + tax_unit: + members: [grandmother, mother, infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, POSTPARTUM, INFANT] + +- name: Mother living alone with her infant is postpartum + period: 2025 + input: + people: + mother: + age: 25 + is_female: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + tax_unit: + members: [mother, infant] + spm_units: + spm_unit: + members: [mother, infant] + families: + family: + members: [mother, infant] + households: + household: + members: [mother, infant] + state_code: TX + output: + wic_category: [POSTPARTUM, INFANT] + +- name: Infant in a tax unit without a mother is matched to the family's youngest mother + period: 2025 + input: + people: + grandmother: + age: 47 + is_female: true + own_children_in_household: 1 + mother: + age: 22 + is_female: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + adults_tax_unit: + members: [grandmother, mother] + infant_tax_unit: + members: [infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, POSTPARTUM, INFANT] + +- name: Breastfeeding mother of an infant aged 0.8 is breastfeeding, the grandmother is not + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + own_children_in_household: 1 + is_breastfeeding: true + infant: + age: 0.8 + tax_units: + tax_unit: + members: [grandmother, mother, infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, BREASTFEEDING, INFANT] + +- name: Breastfeeding mother of an infant aged 0.2 is breastfeeding, the grandmother is not postpartum + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + own_children_in_household: 1 + is_breastfeeding: true + infant: + age: 0.2 + tax_units: + tax_unit: + members: [grandmother, mother, infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, BREASTFEEDING, INFANT] + +- name: A breastfeeding mother of an older infant does not take the postpartum match of another mother's younger infant + period: 2025 + input: + people: + grandmother: + age: 38 + is_female: true + own_children_in_household: 2 + is_breastfeeding: true + mother: + age: 17 + is_female: true + own_children_in_household: 1 + aunt: + age: 0.8 + infant: + age: 0.2 + tax_units: + tax_unit: + members: [grandmother, mother, aunt, infant] + spm_units: + spm_unit: + members: [grandmother, mother, aunt, infant] + families: + family: + members: [grandmother, mother, aunt, infant] + households: + household: + members: [grandmother, mother, aunt, infant] + state_code: TX + output: + wic_category: [BREASTFEEDING, POSTPARTUM, INFANT, INFANT] + +- name: Two mothers with their own infants in one tax unit are both postpartum + period: 2025 + input: + people: + mother_a: + age: 24 + is_female: true + own_children_in_household: 1 + infant_a: + age: 0.3 + mother_b: + age: 21 + is_female: true + own_children_in_household: 1 + infant_b: + age: 0.1 + tax_units: + tax_unit: + members: [mother_a, infant_a, mother_b, infant_b] + spm_units: + spm_unit: + members: [mother_a, infant_a, mother_b, infant_b] + families: + family: + members: [mother_a, infant_a, mother_b, infant_b] + households: + household: + members: [mother_a, infant_a, mother_b, infant_b] + state_code: TX + output: + wic_category: [POSTPARTUM, INFANT, POSTPARTUM, INFANT] + +- name: Father with an infant has no postpartum woman + period: 2025 + input: + people: + father: + age: 30 + own_children_in_household: 1 + infant: + age: 0.2 + output: + wic_category: [NONE, INFANT] + +- name: Mother of an infant aged 0.6 who is not breastfeeding is not postpartum + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + own_children_in_household: 1 + infant: + age: 0.6 + output: + wic_category: [NONE, NONE, INFANT] + +# A woman reported as breastfeeding is matched before the tax-unit heuristic: +# here the grandmother claims the infant, and the infant's mother files alone. +- name: Breastfeeding mother in her own tax unit keeps her infant claimed by the grandmother + period: 2025 + input: + people: + grandmother: + age: 45 + is_female: true + own_children_in_household: 1 + mother: + age: 20 + is_female: true + is_breastfeeding: true + infant: + age: 0.3 + tax_units: + grandmother_tax_unit: + members: [grandmother, infant] + mother_tax_unit: + members: [mother] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, BREASTFEEDING, INFANT] + +# Limitation: a pregnant mother can take the postpartum match (she stays +# PREGNANT, which comes first), so the other mother is not postpartum. +- name: Pregnant younger mother takes the match and stays pregnant + period: 2025 + input: + people: + grandmother: + age: 50 + is_female: true + own_children_in_household: 1 + mother: + age: 25 + is_female: true + is_pregnant: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + tax_unit: + members: [grandmother, mother, infant] + spm_units: + spm_unit: + members: [grandmother, mother, infant] + families: + family: + members: [grandmother, mother, infant] + households: + household: + members: [grandmother, mother, infant] + state_code: TX + output: + wic_category: [NONE, PREGNANT, INFANT] + +# Limitation: one infant makes one woman breastfeeding (the youngest). +- name: Two breastfeeding women and one infant, only the younger is breastfeeding + period: 2025 + input: + people: + woman_1: + age: 30 + is_female: true + is_breastfeeding: true + woman_2: + age: 25 + is_female: true + is_breastfeeding: true + infant: + age: 0.5 + tax_units: + tax_unit: + members: [woman_1, woman_2, infant] + spm_units: + spm_unit: + members: [woman_1, woman_2, infant] + families: + family: + members: [woman_1, woman_2, infant] + households: + household: + members: [woman_1, woman_2, infant] + state_code: TX + output: + wic_category: [NONE, BREASTFEEDING, INFANT] + +# Limitation: in a couple of two women who are both the infant's parents, only +# one can be postpartum (the younger). +- name: Two mothers and one infant in one tax unit, only the younger is postpartum + period: 2025 + input: + people: + parent_1: + age: 32 + is_female: true + own_children_in_household: 1 + parent_2: + age: 30 + is_female: true + own_children_in_household: 1 + infant: + age: 0.2 + tax_units: + tax_unit: + members: [parent_1, parent_2, infant] + spm_units: + spm_unit: + members: [parent_1, parent_2, infant] + families: + family: + members: [parent_1, parent_2, infant] + households: + household: + members: [parent_1, parent_2, infant] + state_code: TX + output: + wic_category: [NONE, POSTPARTUM, INFANT] diff --git a/policyengine_us/variables/gov/usda/wic/wic_category.py b/policyengine_us/variables/gov/usda/wic/wic_category.py index 0953e4ee38d..6f43d0d2855 100644 --- a/policyengine_us/variables/gov/usda/wic/wic_category.py +++ b/policyengine_us/variables/gov/usda/wic/wic_category.py @@ -18,20 +18,72 @@ class wic_category(Variable): default_value = WICCategory.NONE documentation = "Demographic category for the Special Supplemental Nutrition Program for Women, Infants and Children (WIC)" label = "WIC demographic category" - reference = "https://www.law.cornell.edu/uscode/text/42/1786#b" + reference = ( + "https://www.law.cornell.edu/uscode/text/42/1786#b", + "https://www.ecfr.gov/current/title-7/part-246/section-246.2", + ) def formula(person, period, parameters): pregnant = person("is_pregnant", period) mother = person("is_mother", period) breastfeeding = person("is_breastfeeding", period) age = person("age", period) - # Categorize mothers based on the minimum age of children in the SPM unit. - min_age_family = person.family.min(age) + tax_unit = person.tax_unit + family = person.family + # 7 CFR 246.2 defines postpartum and breastfeeding women by the time + # since their own pregnancy (up to six months and one year), so an + # infant makes only its mother postpartum or breastfeeding. Without + # parent-child links, match each infant to at most one woman. + infant = age < 1 + young_infant = age < 0.5 + in_motherless_tax_unit = ~tax_unit.any(mother) + + # 1. A woman reported as breastfeeding is feeding an infant, so match + # her first: to an infant in her tax unit, else to any remaining infant + # in her family (youngest breastfeeding women first). + bf_rank_tax_unit = person.get_rank(tax_unit, age, breastfeeding) + bf_in_tax_unit = breastfeeding & (bf_rank_tax_unit < tax_unit.sum(infant)) + bf_rest = breastfeeding & ~bf_in_tax_unit + bf_rank_family = person.get_rank(family, age, bf_rest) + family_infants_left = family.sum(infant) - family.sum(bf_in_tax_unit) + bf_in_family = bf_rest & (bf_rank_family < family_infants_left) + breastfeeding_woman = bf_in_tax_unit | bf_in_family + + # Take the matched infants out of the pools, oldest first, so that + # breastfeeding women count against infants aged six months to one + # year before younger ones (inputs cannot tell which infant is whose: + # a breastfeeding woman and another mother in one tax unit are assumed + # to have the older and the younger infant). Family matches take + # infants from tax units without a mother first. + infant_rank_tax_unit = person.get_rank(tax_unit, -age, infant) + taken = infant & (infant_rank_tax_unit < tax_unit.sum(bf_in_tax_unit)) + left = infant & ~taken + infant_rank_family = person.get_rank( + family, where(in_motherless_tax_unit, 0, 2) - age, left + ) + taken = taken | (left & (infant_rank_family < family.sum(bf_in_family))) + free_young_infant = young_infant & ~taken + + # 2. Match each remaining infant under six months to one other mother + # in its tax unit, youngest first, and an infant in a tax unit without + # a mother to one of the family's remaining mothers. + candidate = mother & ~breastfeeding_woman + pp_rank_tax_unit = person.get_rank(tax_unit, age, candidate) + pp_in_tax_unit = candidate & ( + pp_rank_tax_unit < tax_unit.sum(free_young_infant) + ) + pp_rest = candidate & ~pp_in_tax_unit + pp_rank_family = person.get_rank(family, age, pp_rest) + pp_in_family = pp_rest & ( + pp_rank_family < family.sum(free_young_infant & in_motherless_tax_unit) + ) + postpartum = pp_in_tax_unit | pp_in_family + return select( [ pregnant, - mother & breastfeeding & (min_age_family < 1), - mother & (min_age_family < 0.5), + breastfeeding_woman, + postpartum, age < 1, age < 5, ],