diff --git a/changelog.d/1095-benefit-target-country-scope.fixed.md b/changelog.d/1095-benefit-target-country-scope.fixed.md new file mode 100644 index 000000000..06da1b293 --- /dev/null +++ b/changelog.d/1095-benefit-target-country-scope.fixed.md @@ -0,0 +1 @@ +The UK benefit rows bound against DWP's lines now sum the households the publisher counts (microcosm#1095, uk-data#490). OBR table 4.9 reports these lines inside "DWP social security", whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own; every row bound the UK column. `obr.pension_credit`, `obr.esa`, `obr.jobseekers_allowance`, `obr.universal_credit` and its two cap rows, `obr.housing_benefit` and `obr.statutory_maternity_pay` now bind Great Britain households, as do the Great Britain caseload facts `dwp.esa_claimants`, `dwp.esa_contrib_claimants`, `dwp.esa_income_claimants`, `dwp.jsa_claimants` and `dwp.benefit_cap.capped_households`. DWP reports Attendance Allowance, Carer's Allowance, DLA/PIP and Winter Fuel Payment for England and Wales only since executive competence moved to the Scottish Government (Carer's Allowance from 3 September 2018, DLA, PIP and Attendance Allowance from 1 April 2020, Winter Fuel Payment from 1 April 2024), and the FRS records Scotland's Pension Age Disability Payment and Carer Support Payment under the Attendance Allowance and Carer's Allowance codes, so `obr.attendance_allowance`, `obr.carers_allowance`, `obr.pip` and `obr.winter_fuel_allowance` bind English and Welsh households. Each row carries the scope twice, as a `uk.geography.country` measurement filter and as a household condition on the binding (region in the eleven Great Britain regions, or country in England and Wales), the form the Pension Credit, State Pension and pension-age Housing Benefit rows already use. Child Benefit stays a UK row: it is an HMRC line that covers Northern Ireland. A test now refuses any active row whose fact is pinned to Great Britain without a Great Britain (or narrower) condition. The target references are unchanged (household conditions are not written into them); the Chronicle facts still carry the UK code, K02000001, which a restamp would correct. diff --git a/changelog.d/1095-constituency-uc-child-bands.fixed.md b/changelog.d/1095-constituency-uc-child-bands.fixed.md new file mode 100644 index 000000000..89ac07a03 --- /dev/null +++ b/changelog.d/1095-constituency-uc-child-bands.fixed.md @@ -0,0 +1 @@ +The UK constituency Universal Credit child bands classify each UC benefit unit with the composition the national UC-by-children rows bind (microcosm#1095, uk-data#486). The bands read the engine's age-18 `num_children`, while the national `dwp.uc.households*` rows count the members DWP's family type treats as children: never a claimant or partner, but any UC child or qualifying young person, or any other member under 20. On the 30 September national build 2.77% of UC-reporting benefit units (0.135m of 4.87m) fell in a different 0, 1, 2 or 3+ band, mostly through 18- and 19-year-old qualifying young people the engine count dropped (72k units moved from 2 to 3+ children and 36k from 0 to 1). One helper, `uc_relationships.uc_family_child_member`, now defines the composition for both, and the national family-type measurement is byte-identical. diff --git a/changelog.d/1095-council-tax-before-reduction.fixed.md b/changelog.d/1095-council-tax-before-reduction.fixed.md new file mode 100644 index 000000000..3c75d93b0 --- /dev/null +++ b/changelog.d/1095-council-tax-before-reduction.fixed.md @@ -0,0 +1 @@ +`council_tax` on the UK spine is the bill before council tax reduction (microcosm#1095, uk-data#496/#499). FRS 2024-25 `CTANNUAL` is the bill after discounts and the reported reduction, while the engine reads `council_tax` as the liability before it, so reduction recipients entered with their reduction already taken off: on the 30 September national build 20.6% of English FRS-channel reduction reporters had a £0 bill and 25.6% a bill below their own reduction (Wales 14.8% and 18.4%, Scotland 0% and 14.4%), and on the raw FRS English recipients' mean bill was £779 against £1,601 for non-recipients. A household reporting a reduction (`CTREB` 1) now gets its `CTREBAMT` added back, a full reduction included, which restores £0.78bn in England, £0.05bn in Wales and £0.06bn in Scotland on the FRS channel; a recipient with no positive amount takes the larger of its bill and its cell mean, and the region, band and single-adult cells pool non-recipients only. Scottish water and sewerage charges come off the bill at the gross cells `CWATAMT1` + `CSEWAMT1`, in full for non-recipients and at 65% for recipients, the shares DWP's derivation embeds; a status-discount check on the raw tab (discounted to undiscounted bills in the same band) gave 0.81 to 0.89 under the earlier netting against the expected 0.75, and 0.75 to 0.76 on the gross cells. The WAS stage's recipient `council_tax` predictor becomes the bill paid, `council_tax` less `council_tax_rebate`, which is what the WAS donor records. The stage refuses a manifest whose rule drifts from the implemented one. diff --git a/changelog.d/1095-etb-family-role-counts.fixed.md b/changelog.d/1095-etb-family-role-counts.fixed.md new file mode 100644 index 000000000..cc7c1e667 --- /dev/null +++ b/changelog.d/1095-etb-family-role-counts.fixed.md @@ -0,0 +1 @@ +The UK ETB VAT and public-services stages count a recipient household's adults and children the way the ETB donor does (microcosm#1095, uk-data#486). The donor's `adults` and `childs` count adults and dependent children, while the recipient side summed the engine's age-18 `is_adult` and `is_child`. On the 30 September national build those disagreed with the FRS child-file count for 2.31% of households (0.67m), mostly households with dependants aged 18 or 19. The recipient counts are now the household's FRS claimants and partners and its other members (`is_uc_claimant`), and only the remaining predictors materialize from the engine. The `etb_services` stage notes also load in full again: an unquoted ` #890` in the YAML had turned the rest of them into a comment. diff --git a/changelog.d/1095-frs-reported-dividends.fixed.md b/changelog.d/1095-frs-reported-dividends.fixed.md new file mode 100644 index 000000000..329b58664 --- /dev/null +++ b/changelog.d/1095-frs-reported-dividends.fixed.md @@ -0,0 +1 @@ +FRS respondents keep their reported dividends on the UK spine (microcosm#1095, uk-data#498). The `hmrc_spi_income_spine` stage redrew `dividend_income` for every FRS-channel person aged 16 or over from the SPI stage-1 forest, whose only predictors are age, gender and region, an operation adopted for parity with the incumbent (microcosm#683). On the 30 September national build that put £30.2bn of dividends on FRS-channel people who reported £4.0bn, only 530 of the 3,872 adults reporting dividends kept any, and benefit units reporting Universal Credit carried £4.07bn against about £0 reported (74.9k of them above £20k), which the engine counts as Universal Credit unearned income; the noise also fed the WAS wealth predictors, the Universal Credit reporter redraw and the capital gains income proxy. The redraw operation, its parameter and its drift checks are removed, and the stage now refuses a manifest that declares one. The keying of the FRS accounts was already on `person_id` (£8.02bn on 1,717 people at FRS design weights), so only the overwrite goes. SPI-channel draws are unchanged: the forest is still queried with every SPI-channel person and the rows outside the recipient domain discarded afterwards. Calibration to the HMRC dividend bands now moves weight between the channels, as in uk-data#498. diff --git a/changelog.d/1095-obr-dla-and-pip-binding.fixed.md b/changelog.d/1095-obr-dla-and-pip-binding.fixed.md new file mode 100644 index 000000000..42fad2803 --- /dev/null +++ b/changelog.d/1095-obr-dla-and-pip-binding.fixed.md @@ -0,0 +1 @@ +`obr.pip` binds the sum of the engine's `pip` and `dla` (microcosm#1095). OBR table 4.9's line is "Disability living allowance and personal independence payments", but the row bound `pip` alone, carried as-is for parity with the incumbent and left for microcosm#622 to adjudicate, which closed without a ruling; on the 30 September national build the solve lifted PIP from £18.9bn to £36.1bn to meet a line that also holds DLA, with the stored DLA (£6.6bn) on top. The row now binds `pip + dla` over English and Welsh households (María's ruling of 2026-10-02), the scope DWP reports both benefits on since 1 April 2020. diff --git a/changelog.d/1095-scottish-disability-payment-codes.fixed.md b/changelog.d/1095-scottish-disability-payment-codes.fixed.md new file mode 100644 index 000000000..bd47a4025 --- /dev/null +++ b/changelog.d/1095-scottish-disability-payment-codes.fixed.md @@ -0,0 +1 @@ +The UK FRS spine maps Scotland's Adult Disability Payment and Child Disability Payment (microcosm#1095, uk-data#500). The FRS 2024-25 BENEFITS table records them under codes 117 and 118 (ADP daily living and mobility) and 121 and 122 (CDP care and mobility), which the spine read nowhere, so every Scottish recipient carried no disability benefit: on the raw FRS 215k adults report ADP daily living (£0.98bn a year), 147k ADP mobility, 51k CDP care and 27k CDP mobility, against 80k Scottish PIP daily-living reporters, and the calibrated build had 24.6 PIP daily-living reporters per 1,000 Scottish residents against 66.0 in England. ADP mirrors PIP's components and rates and CDP mirrors DLA's, so the amounts join the reported columns of the benefits they replace (`pip_dl_reported`, `pip_m_reported`, `dla_sc_reported`, `dla_m_reported`), and the disability categories and flags follow from them as they do for PIP and DLA. The benefit recovery codes 69 and 70 stay unmapped. The OBR PIP, AA and Carer's Allowance rows bind English and Welsh households, so the Scottish payments do not enter a line that excludes them. diff --git a/changelog.d/1095-scottish-water-charge-paid.fixed.md b/changelog.d/1095-scottish-water-charge-paid.fixed.md new file mode 100644 index 000000000..32ce5377e --- /dev/null +++ b/changelog.d/1095-scottish-water-charge-paid.fixed.md @@ -0,0 +1 @@ +Scottish `water_and_sewerage_charges` on the UK spine is the charge the household pays (microcosm#1095, uk-data#499). The spine read each household's discount factor as `CWATAMTD`/`CWATAMT1`, but `CWATAMTD` sits below the gross water charge even where no discount applies (a median 0.83 for undiscounted households on the 2024-25 tab, about £1 a week below in bands B and D to G), which put Scottish charges about 13% to 16% below the gross charges less the status discount, and council tax reduction recipients got no water charges reduction. The charge is now the gross `CWATAMT1` + `CSEWAMT1` less the household's status discount (25% or 50%, from `CTDISC` and `CT25D50D`); for a council tax reduction recipient the Water Charges Reduction Scheme tops that discount up to 35% of the gross charges, the full-reduction case of the 2021-27 scheme's R = 35 × (A/B) − D, so a recipient pays the gross charges less the larger of its discount and 35%. Every recipient takes the full-reduction case because 86% of Scotland's recipients receive full council tax reduction while the FRS-recorded reduction amounts carry none. A household with no gross water cell pays its recorded `CWATAMTD`, and the helper refuses a raw tab without the discount and reduction cells. diff --git a/changelog.d/1095-spi-benefit-coherence.added.md b/changelog.d/1095-spi-benefit-coherence.added.md new file mode 100644 index 000000000..099adbb65 --- /dev/null +++ b/changelog.d/1095-spi-benefit-coherence.added.md @@ -0,0 +1 @@ +New UK spine stage `spi_benefit_coherence` makes the SPI channel's benefit reports and Universal Credit take-up coherent with the households they sit in (microcosm#1095, uk-data#514). The SPI support channel copies whole FRS households and the SPI income stage's FRS-only forests re-impute each adult's benefit reports from age, gender, region and the new incomes, with nothing of the benefit unit's entitlement or claim history. On the 30 September national build the SPI rows reported Income Support, Working and Child Tax Credit and income-based JSA at 2.6 to 9.1 times the FRS rate and contributory JSA at 17 times (two thirds of its SPI reporters earning above the permitted-work limit), held 64%, 72% and 67% of the reported Industrial Injuries Disablement Benefit, Armed Forces Compensation Scheme and bereavement support, kept the FRS twin's `receives_benefits_in_own_right` (3.04m SPI persons disagreed with their own reports) and kept the twin's Universal Credit take-up anchor (1.51m SPI benefit units claimed only because the twin reported Universal Credit). The stage runs after `uc_reporter_redraw`, the last writer of Universal Credit reports, and before `uc_capital_coherence` and the Pension Credit and Child Benefit take-up stages. On SPI-channel rows only, it zeroes the contributory and income-based JSA, income-related ESA, Income Support, tax credit, Severe Disablement Allowance and Sure Start Maternity Grant reports (policyengine-uk pays a reported income-related ESA award behind a capital test alone, and 56% of the SPI units carrying one had incomes above £12,570); restores IIDB, AFCS and bereavement support from the FRS twin; re-derives the disability flags (the categories are asserted unchanged) and `receives_benefits_in_own_right` from the final reports; and redraws `would_claim_uc` for SPI benefit units as `frs_take_up` draws it for FRS units: a unit with a Universal Credit reporter claims, and the rest of the Universal Credit age population claims as the residual of the contract's rate on draws keyed on the SPI unit's identity. Contributory ESA, which is open to new claims and not income-tested, PIP, DLA, AA, Carer's Allowance, State Pension and Winter Fuel Payment keep their draws, and FRS rows are never modified. The release-blocking stage-health gate `uk_stage_spi_benefit_coherence` checks the structural zeros: no SPI row keeps a zeroed report, restored reports equal the twin's, the own-right flag agrees with each person's reports, FRS rows are unchanged, every SPI unit with a Universal Credit reporter claims and no SPI unit outside the population claims without reporting. diff --git a/changelog.d/1095-spi-capital-by-investment-income.fixed.md b/changelog.d/1095-spi-capital-by-investment-income.fixed.md new file mode 100644 index 000000000..66aee796f --- /dev/null +++ b/changelog.d/1095-spi-capital-by-investment-income.fixed.md @@ -0,0 +1 @@ +The UK spine redraws every SPI benefit unit's capital conditioned on its investment income (microcosm#1095, uk-data#495). `uc_capital_coherence` redrew `frs_benunit_capital` (TOTCAPB4) only for SPI-channel units reporting Universal Credit, by children band and couple status, and every other SPI unit kept the capital its FRS parent reported against SPI-drawn incomes: on the 30 September national build 2.28m SPI benefit units had interest and dividends implying more than £16,000 at 4% while holding £16,000 or less, 105k of them Universal Credit reporters, and 14% of SPI units with interest held no capital. The stage now redraws every SPI unit from the base units with an available answer, in cells of Universal Credit reporter status by financial investment income band (interest, dividends and other investment income: none, then up to the income that £6,000, £16,000, £50,000 and £200,000 yield at 4%, then above) by couple status by children band. A cell with fewer than 20 donors widens in a declared order (children bands merged, couple status dropped, adjacent income bands merged, then reporter status alone), and reporter status never coarsens. Property income stays out of the cells because TOTCAPB4 counts accounts and assets. The stage evidence records the units drawn at each coarsening level and, by channel, the units whose income implies capital above £6,000 or £16,000 while they hold no more, before and after the redraw. diff --git a/changelog.d/1095-spi-draws-skip-dependants.fixed.md b/changelog.d/1095-spi-draws-skip-dependants.fixed.md new file mode 100644 index 000000000..84ffc7dd9 --- /dev/null +++ b/changelog.d/1095-spi-draws-skip-dependants.fixed.md @@ -0,0 +1 @@ +The UK SPI income stage draws only for claimants and partners aged 16 and over (microcosm#1095, uk-data#504). Its recipient guard was age-only, so dependent children aged 16 to 19 in the SPI channel took taxpayer draws from the tape: on the 30 September national build 93% of SPI-channel 16- and 17-year-olds had earnings, £11.0bn on 0.81m people, against 4% on the FRS channel; £0.95bn of it sat in benefit units reporting Universal Credit, where the engine counts a member's earnings against the unit; and 12 income band donor carriers aged 16 or 17 held draws of £200,000 or more. Recipients are now SPI-channel people aged 16 and over whose `is_uc_claimant` (the FRS adult-file role from `frs_uc_claimant_mask`) is set, and one mask drives the stage-1 and stage-2 assignments, the State Pension guards, the HMRC auxiliaries and the disability and carer refreshes, so a dependant keeps every value of its FRS twin. Both forests are still queried over every SPI-channel person aged 16 and over and the dependants' rows discarded afterwards, so every other recipient keeps its draw. Income band donor carriers are drawn from claimants and partners too, the income stage refuses a carrier outside the recipient domain, and the stage evidence records the dependant rows and weight kept on twin values. diff --git a/changelog.d/1095-was-buy-to-let.fixed.md b/changelog.d/1095-was-buy-to-let.fixed.md new file mode 100644 index 000000000..98c88a89f --- /dev/null +++ b/changelog.d/1095-was-buy-to-let.fixed.md @@ -0,0 +1 @@ +`other_residential_property_value` on the UK spine includes buy-to-let property (microcosm#1095, uk-data#501). The WAS stage drew it from `DVHseValR8_sum` alone, the houses other than the main residence. That left `DVBltValR8_sum`, buy-to-let property worth £573bn at WAS weights across 1,351 donor households, in the undrawn other-property remainder that only `property_wealth` carries. On the donor, 24.6% of households receiving rent held other residential or non-residential property before the change and 90.5% after it. The column is now `DVHseValR8_sum + DVBltValR8_sum`, the remainder shrinks by the same amount, and `property_wealth` and its identities are unchanged. The WAS support bounds are unchanged at their one-significant-figure rounding (`tools/build_uk_was_wealth_support_bounds.py --check` passes on the licensed tab). diff --git a/changelog.d/1095-was-predictor-definitions.fixed.md b/changelog.d/1095-was-predictor-definitions.fixed.md new file mode 100644 index 000000000..ed380d959 --- /dev/null +++ b/changelog.d/1095-was-predictor-definitions.fixed.md @@ -0,0 +1 @@ +The UK WAS wealth stage's predictors measure the same things on the donor and the recipient (microcosm#1095, uk-data#486/#495). The donor's council tax was `CTAmtR8`, a single instalment (weighted mean £479 against £1,395 for the annual amount paid, `DVCTaxAmtAnnualR8`). Its children were `NumCh18R8`, which also counts the 16- and 17-year-olds that `NumAdultR8` counts, so the two overrun the household size on 5.6% of donor rows. The recipient's adults and children were the engine's age-18 counts. The donor now reads `DVCTaxAmtAnnualR8` and `NumChildR8` (`NumChildR8` + `NumAdultR8` is the household size on 99.99% of rows). The recipient's adults and children are its FRS claimants and partners and its other members (`is_uc_claimant`), which the Lifetime ISA stage reads through the same surface. A new `rental_income` predictor pairs the donor's net rent `DVNetRentAmtAnnualR8_aggr` with the household's property income: WAS investment income excludes rent, so the property draws had no income of their own, and on the 30 September national build 91% of households with rental income held no other residential or non-residential property. The stage refuses a manifest whose predictor lists drift from the code's. diff --git a/docs/uk-income-anchors-280.md b/docs/uk-income-anchors-280.md index e83f753cb..c12043d49 100644 --- a/docs/uk-income-anchors-280.md +++ b/docs/uk-income-anchors-280.md @@ -255,8 +255,9 @@ FRS parent's income, while its adults' incomes were replaced by SPI draws. A was copied from. With the SPI block first, every row, the FRS base rows included, is imputed -from its final incomes. On the base rows this includes the SPI stage-1 -dividend redraw. +from its final incomes. The base rows' incomes are their own reports: the SPI +stage-1 forest no longer redraws their dividends (uk-data#498, +microcosm#1095). Three details follow from the order: diff --git a/experiments/1095-uk-data-ports-receipts.md b/experiments/1095-uk-data-ports-receipts.md new file mode 100644 index 000000000..e0f60866b --- /dev/null +++ b/experiments/1095-uk-data-ports-receipts.md @@ -0,0 +1,254 @@ +# microcosm#1095 receipts: the unblocked uk-data ports + +Plan: `repos/microcosm-1095-ports-plan.md` (approved 2026-10-02). Branch `uk-data-ports-1095`. It was +stacked on `uk-spine-followups-1063` (#1089). After #1089 merged (`48fa06166`, 2026-10-04) it targets +main and is rebased onto it. The rebase replayed every commit; the only conflicts were the generated +coverage manifest and H2 fixture, which were regenerated after each replayed commit, and each commit's +other changes are line-for-line those of its pre-rebase original. The tracker is #1095 (uk-data items +up to uk-data#519). + +Commits, in order (hashes on main): + +- 1d1c10da3 C4a: the DWP and OBR table 4.9 benefit rows bind the households their publisher counts. +- 3c1b33f34 C4b: `obr.pip` binds the engine's `pip + dla`. +- 04ea9943b C5: Scottish Adult and Child Disability Payment codes on the FRS spine (uk-data#500). +- 90621f74a C1: FRS-reported dividends kept (uk-data#498). +- f0c30271d C2: SPI draws only for FRS claimants and partners (uk-data#504). +- 07e5b0f9c C3a: council tax before council tax reduction (uk-data#496/#499). +- 746940855 C3b: the Scottish water and sewerage charge paid (uk-data#499). +- 790f36ffd C6: the `spi_benefit_coherence` stage and its gate (uk-data#514). +- c58fc84d3 C7: SPI benefit-unit capital conditioned on investment income (uk-data#495). +- adfcc079e C8a: the WAS predictors measured alike on donor and recipient (uk-data#486/#495). +- 49d26eceb C8b: buy-to-let as other residential property (uk-data#501). +- 39af74a21 C9a: the ETB adult and child counts by FRS family role (uk-data#486). +- 8ede090d8 C9b: the constituency UC child bands on the national UC composition (uk-data#486). +- 7efa9d00b C10: the South East £12,570 to £15,000 income-tax deferral retired, because the ports + make it stale. +- 1a4f934ce C11: the first version of this note. +- eaf7e80cf R1: income-related ESA zeroed on SPI rows (review round 1, item 3). +- d89a3ddfe R2: the Scottish water charge at the reduction scheme's combined maximum (item 4). +- 894a33c19 R2 test: the FRS mapping test's Scottish water value. +- a0c678c21 R3: the three input-mass exclusions the ports make stale, retired. +- R4: this update of the note. + +C4c, the Housing Benefit pension-age spending row, was dropped. The DWP forecast-table facts carry +one `measure_id` per year (`expenditure_2024`, `expenditure_2025`), and `calendar_year_window` +needs both fiscal years from one series identity. The row needs a Chronicle series-identity change +or a ruling to bind FY2025-26 alone. + +## Rulings (2026-10-02) + +- Buy-to-let (`DVBltValR8_sum`) goes into `other_residential_property_value`. +- Scottish council tax follows two rules. The netting is uk-data#499's: the gross `CWATAMT1` + + `CSEWAMT1`, in full for non-recipients and at 65% for reduction recipients. The charge paid is the + gross charges less the status discount, at 65% for reduction recipients. Review round 1 refines the + charge to the scheme's own formula (below). +- `obr.pip` binds PIP + DLA over England and Wales. +- The full SPI benefit-coherence stage, including the UC take-up redraw. + +## Review round 1 (2026-10-04) + +- **Income-related ESA (R1).** policyengine-uk pays `esa_income_reported` as the award, screened + only by a capital test, so an SPI row keeping its stage-2 draw was paid its twin's award whatever + its new incomes. + - On the A8 spine at design weights, SPI rows held 0.15m of the 0.53m income-related ESA + reporters (29%) and £1.45bn of reports; 56% of their benefit units had incomes above £12,570 and + 43% above £20,000. + - `spi_benefit_coherence` now zeroes it with income-based JSA and Income Support, as uk-data#514 + does. + - Contributory ESA keeps its draw: it is open to new claims and not income-tested, its incapacity + test follows the person, its SPI draw sits at half the FRS rate per working-age adult, and 9.9% + of its SPI reporters by weight earn above the permitted-work limit (41% on the uk-data build + where #514 zeroes it). +- **Scottish water (R2).** The Scottish Government's charging principles for 2021-27 (Annex A) set + a reduction recipient's water reduction at R = 35 × (A/B) − D points of the gross charge, unless + negative, on top of the status discount D; A is the council tax reduction and B the council tax + before it. + - The combined reduction is max(D, 35% × A/B). C3b had stacked the 35% on the discount, so a + single person on full reduction paid 48.75% of the gross charge instead of 65%; 207 of the 245 + Scottish recipients on the raw tab carry the 25% discount. + - Every recipient takes the full-reduction case, A/B = 1. 86% of Scotland's 458,120 recipients + receive full reduction (Council Tax Reduction in Scotland 2024-25, March 2025; average award + £16.55 a week), while none of the 234 Scottish recipients with a recorded `CTREBAMT` on the FRS + 2024-25 tab pays nothing after it (19% of English recipients do), and their amounts have a + median of £6 a week. The recorded amount cannot carry the share. + - On the raw tab, recipients pay 0.649 of the gross charges instead of 0.511. The netting of + `CTANNUAL` keeps 0.65. +- **Input-mass register (R3).** See Verification. +- **VAT.** No change here; see Fit by arm. + + +## Builds + +Every arm is a licensed local build in the detached measurement tree `repos/populace-1095-shard` +(`data/ukds/acceptance/1095-uk-data-ports/scripts/arm.sh calibrate`, queued by +`run_arms.sh`): the spine with the build_930 recipe (the five NTS tabs, `--was-person-tab`, +`--no-staging`), then the national calibration with local staging only, against the Chronicle +artifact 825406f. Nothing is released from an arm, and the engine is policyengine-uk at the repo's +pin. + +The arms are cumulative. A0 to A7 ran on the pre-rebase chain on `747313ae7`. A0 is the control: +#1089 at `747313ae7`, calibrate-only on #1089's own stack-2 spine. A1 recalibrates that spine with +C4, since C4 only changes targets. A2 to A7 each build their own spine. A8 built the head rebased on +#1089's `45014f48c` (`9c7394086`, the ports without C10 and C11, which touch no spine code). + +A9 builds `d89a3ddfe`: every port and both review fixes, on main. The commits after it (the test pin, +the input-mass register and this note) touch no spine or calibration code, so A9 measures the code +at the PR head. The control for A9 is main's own final #1089 build at `64c460b66` +(`runs/uk-national-1063-64c460b66`), whose spine and calibration code main carries unchanged. + +Figures from the spines are at design weights. Counts resting on fewer than 10 records are +suppressed. + +## Fit by arm + +The national problem has 1,168 targets throughout. The gate failures listed come from the +calibrated-seam battery; arms A3 to A7 wrote their evidence bundle but no H5. + +- **A0, control.** Loss 0.28290 to 0.00720; 98.3% of targets within 10%; ESS 4,937. All 7 gates + pass. +- **A1, + C4.** Loss 0.00719; 98.3% within 10%; all 7 gates pass. + - `obr.pip` design value £19.4bn becomes £23.6bn once DLA is bound with PIP; it calibrates on + target either way. + - The rescoped benefit rows keep a mean absolute error of 1.0%. +- **A2, + C5.** Loss 0.00716; 98.4% within 10%; all 7 gates pass. +- **A3, + C1 and C2.** Loss 0.00707; 98.5% within 10%. `uk_target_fit` fails twice: + - `obr.vat` at +25.2%, just over the 25% bound (+22.8% at A0); + - #1089's reviewed exclusion of `hmrc.spi_region.income_tax_by_region_12570_15000@E12000008@2025` + is stale: the South East £12,570 to £15,000 income-tax cell calibrates at +8.0% (+31.3% at A0), + and the gate requires stale exclusions to be removed. + - All 16 rescoped benefit rows and all 4 ESA rows are within 10%. +- **A4, + C3a and C3b.** Loss 0.00703; 98.6% within 10%. Only the stale exclusion fails. + - `obr.council_tax` is at −10.3% (−11.6% at A3): the design value rises from £44.1bn to £44.9bn. +- **A5, + C6 and C7.** Loss 0.00697; 98.5% within 10%. + - `uk_target_fit` fails on `obr.vat` at +25.0% and on the stale exclusion. + - `uk_weight_ratio` fails at 1,161.8 against the reviewed maximum of 1,151.3. +- **A6, + C8a and C8b.** Loss 0.00693; 98.5% within 10%. Only the stale exclusion fails. + - `obr.council_tax` is at −9.9%, inside 10% for the first time; all 98 council-tax rows are + within 10%. +- **A7, + C9a and C9b.** Loss 0.00702; 98.5% within 10%; ESS 4,795. Only the stale exclusion + fails. + - `obr.vat` is at +24.4%, the South East cell at +12.1%, and `obr.council_tax` at −9.9%. +- **A8, the rebased PR head.** Loss 0.28848 to 0.00693; 98.8% within 10%, the best of the arms; + ESS 4,844. + - The only gate failure is the stale South East deferral: the cell fits at +11.7%. C10 retires + it, so the battery passes on the code this PR proposes. + - `obr.vat` is at +24.998% against the 25% bound, and `obr.council_tax` at −9.9%. + +- **A9, the review head on main.** Loss 0.29242 to 0.00715; 99.0% within 10%, the best of the + arms, with 12 targets outside 10%; ESS 4,828. All 7 gates pass. + - Against main's own build (loss 0.00713, 98.4% within 10%, 19 targets outside 10%, ESS 4,973): + the South East £12,570 to £15,000 cell is at +11.5% (+30.3% on main, deferred there), and + `obr.council_tax` at −9.9% (−11.1%). + - `obr.vat` is at +24.4% (+23.1% on main): 0.6 points inside the bound. + - Zeroing income-related ESA on SPI rows lowers the design `obr.esa` from £5.73bn (A8) to £4.80bn + and the design `dwp.esa_income_claimants` from 404k to 313k. Calibration restores both: +0.4% + and −0.1%. `dwp.esa_claimants` lands at +11.9% (+9.3% at A8, +11.0% on main), inside the gate + bound. + +`obr.vat` sits 1.6 to 2.4 points nearer its bound from A3 on than at A0. Design VAT falls from +£227bn (A0) to £224bn (A3) and £222bn (A7), while calibrated VAT rises from £218bn to £223bn and +£221bn. The closeness therefore comes from how calibration trades VAT against the income rows once +FRS dividends stand as reported. + +At A8 VAT passed by 0.002 points (+24.998%); at A9 it passes by 0.6 points (+24.4%), against ++23.1% on main without the ports. The overshoot itself predates the ports: design VAT is 25% to 28% +over the OBR line in every arm and on main. Its level comes from the engine, which divides household +VAT by `microdata_vat_coverage`, 0.383 since 2010, where this dataset's consumption implies about +0.46 (PolicyEngine/policyengine-uk#1996, filed from #1063, where María ruled VAT an engine fix). + +## Spine receipts by commit + +- **C5 (A2).** Scottish PIP daily-living reporters per 1,000 residents rise from 13.2 to 43.9. + Wales is at 61.3 and the North West at 54.7. +- **C1 (A3).** Dividends on the FRS channel fall from £40.5bn to £5.1bn, the respondents' own + reports. The SPI channel goes from £55.5bn to £57.3bn. + - Benefit units whose interest and dividends imply more than £16,000 at 4% while they hold + £16,000 or less fall on the FRS channel from 1.62m to 0.21m. + - The redrawn dividends had made that incoherence. +- **C2 (A3).** SPI-channel dependants aged 16 to 19 with earnings fall from 94.2% to none. Their + earnings were £12.0bn; too few records keep any to report a figure. + - Income band donor carriers who are dependants fall from 40 to 0. + - The income stage keeps 692 dependant rows (0.84m people) on their twin's values. +- **C3a (A4).** Among households reporting a council tax reduction, the share with a £0 bill falls + from 10.6% to 0, and the share billed below their own reduction from 13.8% to 0. + - Council tax at design weights moves from £37.0bn to £38.3bn in England and from £2.08bn to + £2.18bn in Wales. + - Scotland falls from £3.21bn to £3.06bn, because the gross water and sewerage charges now come + off the bill in full for non-recipients. +- **C3b (A4).** The mean Scottish water and sewerage charge rises from £404 to £465. England and + Wales are at roughly £490. +- **C6 (A5).** At the stage, 435 SPI rows reported contributory or income-based JSA, Income + Support, Working or Child Tax Credit, SDA or the Sure Start Maternity Grant; none do afterwards. + - At design weights that was £2.50bn of reports, £0.81bn of it Child Tax Credit. + - AFCS on SPI rows returns from £0.79bn to its twins' £0.21bn, bereavement support from £0.38bn + to £0.30bn, and IIDB moves from £0.13bn to £0.15bn. + - `receives_benefits_in_own_right` changes on 2,316 SPI rows (2.98m people), and no row + disagrees with its own reports afterwards. + - The UC take-up redraw sets 2,612 SPI units to claim and 2,422 not to, at the contract rate of + 0.55. Every SPI reporter unit claims, and no unit outside the UC age population claims without + reporting. + - `uc_capital_coherence`'s OR refresh becomes a no-op (0 units). +- **C7 (A5).** SPI units whose investment income implies more than £16,000 while they hold £16,000 + or less fall from 1.86m to 0.18m (above £6,000: from 1.94m to 0.14m). + - 13,836 of 14,245 SPI units drew from their exact cell; 359 merged children bands, 50 merged + adjacent income bands, and none fell back to reporter status alone. + - Four SPI reporter units hold more than £16,000 after the redraw. +- **C8b (A6).** Households with rental income that hold other residential or non-residential + property rise from 11.6% to 88.3%. +- **C9a and C9b.** In 1.8% of households the engine's age-18 adult count differs from the FRS + family roles. Those households now feed the WAS and ETB predictors and the constituency UC bands + the role counts. The national UC family-type measurement is byte-identical by construction. +- **R1 (A9).** No SPI row reports income-related ESA; on A8 the SPI rows carried 258 such records, + £1.45bn at design weights. The FRS rows are unchanged (860 records, £3.58bn), and contributory ESA + keeps its SPI draws (187 records, £0.58bn). +- **R2 (A9).** The mean Scottish water and sewerage charge at design weights rises from £465 (A4 to + A8) to £474. On the raw tab the mean annual charge of a reduction recipient rises from £238 to + £300 at FRS grossing weights. + +## Verification + +On main the PR gets CI. Locally, with the pinned feed set: + +- **Touched surface on the rebased head (`d89a3ddfe`):** 95 test files, 2,047 tests. They are every + test the commits change, every test importing a touched runtime module, test-support helper or + tool, H2 parity, and the tests where #1089's later commits meet these: the national graph, target + references, UC family, battery bindings, identity stability, terminal gates, release certification + and weighted integrity. + - 2,038 passed, 6 skipped and 3 failed. + - `test_household_and_benunit_mapping_values_are_ported` pinned the Scottish water value at the + stacked rule. It is fixed in 894a33c19, and it was CI's only engine-free failure. + - `test_engine_is_reported_unavailable_without_the_uk_extra` needs a venv without the UK extra: + an environment failure. + - `test_committed_surfaces_regenerate_from_pinned_feed[national]` fails on main as it does here. + The committed `target_references.json` (bf7549…) no longer regenerates (e8f829…). Neither the + file nor its generator has changed since #1089's `2fe7d8bbb`, and CI skips the test because it + has no licensed feed. + - The other three failures listed on the old base pass on main, after #1089's later commits: + national compile parity, the national graph's `uk_target_fit`, and the UC payment registry. +- **Gate digests:** `repin_digests --check` reports 0 of 12 moved after the rebase. R1 moves 5, for + the gate's new zeroed column, and re-pins them in the same commit. +- **Input-mass register (R3).** + - I ran the release-cut `input_mass_parity` gate with the certifier's own functions on A9's spine + at its calibrated weights, against the v1.56.16 reference. The script is + `data/ukds/acceptance/1095-uk-data-ports/scripts/input_mass_check.py`, and it reproduces the + certifier's verdict on main's `64c460b66` build exactly. + - The gate fails only on three stale exclusions, all inside the 452% fence: + - income-based JSA at £97.7m (+316%); + - Working Tax Credit at £149.6m (+103%); + - the access fund at £258.6m (+62%). + - With R3's register the gate passes, with `dfe_education_spending` its only exclusion. + - The other columns the ports touch stay inside the fence: income-related ESA +5.0%, Income + Support −71.6%, AFCS −78.9%, and `other_residential_property_value` −31.1% (−73.5% on main). +- `tools/build_uk_release_input_coverage_manifest.py --check` and `tools/ci_test_plan.py verify`: + ok. + +## Signature drafts + +These are not committed: + +- the new signed difference `council-tax-gross-of-reduction`; +- the amended `scottish-water-sewerage-successor-level`; +- the reworded `uc_unit_vs_household_grain` adjudication and its census fence. + +The drafts are in the PR description. diff --git a/packages/microcosm-build/src/microcosm/build/source_manifest.py b/packages/microcosm-build/src/microcosm/build/source_manifest.py index 4ee2065fc..2588173e1 100644 --- a/packages/microcosm-build/src/microcosm/build/source_manifest.py +++ b/packages/microcosm-build/src/microcosm/build/source_manifest.py @@ -159,7 +159,9 @@ "read_acs_rent_donor", "redraw_columns_from_fitted_qrf", "resample_band_donor_leaves", + "restore_spi_channel_reports_from_source", "zero_pension_age_reports_below_state_pension_age", + "zero_spi_channel_reports", "redraw_spi_reported_uc", "redraw_spi_reporter_capital", "record_mass_conservation_receipt", diff --git a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/sources.schema.json b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/sources.schema.json index 57c738af1..839249b19 100644 --- a/packages/microcosm-build/src/microcosm/build/spec_engine/schema/sources.schema.json +++ b/packages/microcosm-build/src/microcosm/build/spec_engine/schema/sources.schema.json @@ -6586,6 +6586,9 @@ "population": { "type": "string" }, + "rows": { + "type": "string" + }, "seed": { "type": "integer" } @@ -7665,6 +7668,9 @@ "type": "integer", "minimum": 0 }, + "recipient_role_column": { + "type": "string" + }, "rebase_income_to_build_period": { "type": "boolean" }, @@ -7990,6 +7996,11 @@ "output", "rows", "donor_rows", + "reporter_status", + "investment_income", + "investment_income_band_edges", + "minimum_cell_donors", + "coarsening", "dependent_children_bands", "couple_status", "weight_mapping", @@ -8011,6 +8022,30 @@ "donor_rows": { "type": "string" }, + "reporter_status": { + "type": "string" + }, + "investment_income": { + "type": "string" + }, + "investment_income_band_edges": { + "type": "array", + "minItems": 1, + "items": { + "type": "number" + } + }, + "minimum_cell_donors": { + "type": "integer", + "minimum": 1 + }, + "coarsening": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, "dependent_children_bands": { "type": "array", "minItems": 4, @@ -9016,6 +9051,66 @@ } } }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "rows", + "columns", + "reason" + ], + "properties": { + "kind": { + "const": "zero_spi_channel_reports" + }, + "rows": { + "type": "string" + }, + "columns": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "reason": { + "type": "string" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "rows", + "columns", + "linkage", + "reason" + ], + "properties": { + "kind": { + "const": "restore_spi_channel_reports_from_source" + }, + "rows": { + "type": "string" + }, + "columns": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "linkage": { + "type": "string" + }, + "reason": { + "type": "string" + } + } + }, { "type": "object", "additionalProperties": false, diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index aeb01125e..e2b38403b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -458,6 +458,33 @@ }, "notes": "Stage-time SPI redraw identity gate over the HMRC SPI income spine receipt." }, + { + "id": "uk_stage_spi_benefit_coherence", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "parameters": { + "stage": "spi_benefit_coherence", + "check": "spi_benefit_coherence", + "zeroed_columns": [ + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported" + ], + "restored_columns": [ + "iidb_reported", + "afcs_reported", + "bsp_reported" + ] + }, + "notes": "Stage-time structural gate over the SPI benefit coherence receipt (microcosm#1095, uk-data#514): no SPI-channel row keeps a zeroed legacy report, every restored report equals the FRS twin's, receives_benefits_in_own_right agrees with each person's own reports, FRS rows are unchanged, every SPI benefit unit with a Universal Credit reporter claims, and no SPI unit outside the Universal Credit age population claims without reporting." + }, { "id": "uk_stage_pension_credit_take_up", "gate": "stage_health", @@ -961,7 +988,7 @@ "parameters": { "maximum_share_deviation": 0.05 }, - "notes": "Every contract-driven stochastic flag must be non-constant and have a weighted share within +/-0.05 of its contract target. would_claim_pc is measured by uk_stage_pension_credit_take_up instead (microcosm#1069 R9), and would_claim_child_benefit and child_benefit_opts_out by uk_stage_child_benefit_take_up (microcosm#1063)." + "notes": "Every contract-driven stochastic flag must be non-constant and have a weighted share within +/-0.05 of its contract target. would_claim_pc is measured by uk_stage_pension_credit_take_up instead (microcosm#1069 R9), and would_claim_child_benefit and child_benefit_opts_out by uk_stage_child_benefit_take_up (microcosm#1063). would_claim_uc is drawn for FRS benefit units by frs_take_up and redrawn for SPI-channel units by spi_benefit_coherence on the same rule (microcosm#1095), so the gate measures both channels at the contract rate." }, { "id": "uk_brma_enum_domain", diff --git a/packages/microcosm-build/src/microcosm/build/uk/input_mass_reviewed_exclusions.json b/packages/microcosm-build/src/microcosm/build/uk/input_mass_reviewed_exclusions.json index c3df7a683..d7e3131ca 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/input_mass_reviewed_exclusions.json +++ b/packages/microcosm-build/src/microcosm/build/uk/input_mass_reviewed_exclusions.json @@ -3,33 +3,12 @@ "description": "Reviewed input-mass parity exclusions for the UK terminal battery, scoped per named comparison reference (microcosm#630): an exclusion suppresses only when its reference is the armed one, so a column excluded on a channel-blind reference is compared normally against a channel-aware one with no register change. Each entry is a complete approval receipt (schema-2 fields per #610). The gate reports dormant entries, FAILS stale ones, and FAILS expired ones until the adjudication is renewed, so this register cannot rot.", "references": { "efrs-post-calibration": { - "access_fund": { - "reason": "One FRS household carries 98% of the candidate's access-fund mass (GBP 1.01bn against the incumbent's GBP 160m, +535%): sernum 14443's 19-year-old reports an access fund of GBP 4,500 with FRS period code 5 (calendar month), which the FRS weeklyises to GBP 1,035.62 (ACCSSAMT) and the spine annualises to GBP 54,037, eleven times the next largest FRS value; the calibration takes the household and its two capital-gains copies to the 10x weight bound. The value is almost certainly an annual or termly award under the wrong period code; the input stays on the release surface until the period rule is settled in the spine, and the exclusion expires with it.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-01-04" - }, "dfe_education_spending": { "reason": "The candidate carries DfE education spending through the build (GBP 98.8bn against the incumbent's GBP 52.8m, +187,061%): the enhanced-FRS reference carries almost none of this input, so the comparison measures the reference's omission, not the candidate's. The input stays on the release surface and in the coverage manifest.", "approved_by": "juaristi22", "adjudication": "microcosm#1063 c9 (certifier rehearsal R5 on the 2026-09-30 build, 2026-10-01; ruling 2026-10-02 in session)", "approved_on": "2026-10-02", "expires_on": "2027-04-02" - }, - "jsa_income_reported": { - "reason": "The candidate carries GBP 272m of reported income-based JSA against the incumbent's GBP 23m (+1,058%): the enhanced-FRS reference holds only the FRS respondents' amounts, while the spine's SPI synthetic channel receives this legacy-benefit leaf from the stage-2 QRF at FRS rates (76 of the 196 nonzero rows and most of the mass) and a few rows sit at the calibration's weight bound. Neither is new to this build: the 2026-09-30 main candidate stood at +428% on the same column. The comparison measures the SPI channel's imputation of a legacy benefit, which is a design question for the channel, not a mass the candidate lost or invented.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-04-04" - }, - "working_tax_credit_reported": { - "reason": "The candidate carries GBP 625m of reported Working Tax Credit against the incumbent's GBP 74m (+747%): the enhanced-FRS reference holds only the FRS respondents' amounts, while the spine's SPI synthetic channel receives this legacy-benefit leaf from the stage-2 QRF at FRS rates (274 of the 372 nonzero rows) and a few rows sit at the calibration's weight bound. The 2026-09-30 main candidate stood at +421% on the same column. Tax credits closed in April 2025, so the SPI channel's treatment of the leaf is a design question for the channel, not a mass the candidate lost or invented.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-04-04" } } } diff --git a/packages/microcosm-build/src/microcosm/build/uk/release_input_coverage_manifest.json b/packages/microcosm-build/src/microcosm/build/uk/release_input_coverage_manifest.json index b98488cfe..7a10f5817 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/release_input_coverage_manifest.json +++ b/packages/microcosm-build/src/microcosm/build/uk/release_input_coverage_manifest.json @@ -468,7 +468,7 @@ "required_mass_change_reason": "Capital-gains incidence anchor moves the mass of non-liable clone households back to their paired originals until the sub-exempt and loss-making clone mass match the Advani-Summers reporter composition at the redrawn liable mass; every pair's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Advani and Summers (2020), Capital Gains and UK Inequality, CAGE Working Paper 465", "survey": "Family Resources Survey 2024-25, SPI synthetic support, the HMRC Table 3 redrawn gains on the spine and Advani-Summers capital-gains incidence" @@ -491,7 +491,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Advani and Summers (2020), Capital Gains and UK Inequality, CAGE Working Paper 465", "survey": "Family Resources Survey 2024-25, SPI synthetic support, and Advani-Summers capital-gains incidence" @@ -514,7 +514,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -536,7 +536,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -565,7 +565,7 @@ "required_mass_change_reason": "ETB public-services imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "UK Data Service SN 8856 Effects of Taxes and Benefits household tab, DfT rail fare index, and public NHS activity/cost table.", "survey": "Effects of Taxes and Benefits 1977-2024 and NHS age-gender public table" @@ -585,7 +585,7 @@ "required_mass_change_reason": "ETB VAT expenditure-rate imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "UK Data Service SN 8856 Effects of Taxes and Benefits household tab and cited VAT anchor resource.", "survey": "Effects of Taxes and Benefits 1977-2024" @@ -606,7 +606,7 @@ "required_mass_change_reason": "CGT asset-type assignment on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -630,7 +630,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "067ba21c12aeb4e95e6a8a16141dbaa075e8787ed875a005f549cab6e91a6b56", @@ -719,7 +719,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -760,7 +760,7 @@ "required_mass_change_reason": "LCFS consumption imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "UK Data Service SN 9468 Living Costs and Food Survey 2023-24 household/person tabs and the vendored Chronicle facts for NEED 2023 mean kWh, the FY2024-25 Ofgem cap levels, road-fuel outturn (DESNZ, HMRC, ONS), the DfT VEH1103 licensed-car stock, NTS bus use and the DfT and devolved bus finance tables.", "survey": "Living Costs and Food Survey 2023-24" @@ -786,7 +786,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Department for Transport National Travel Survey, UK Data Service SN 5340 (End User Licence, 19th edition, November 2025), DOI 10.5255/UKDA-SN-5340-19; local licensed tab files (household, individual, trip); England residents only from 2013.", "survey": "National Travel Survey 2002-2024" @@ -810,7 +810,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "MHCLG dwellings and ONS UK House Price Index December 2025 regional average prices.", "survey": "Public regional property reference" @@ -837,7 +837,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "HMRC, Salary sacrifice reform for pension contributions effective from 6 April 2029", "survey": "Family Resources Survey 2024-25 salary-sacrifice respondents and HMRC salary-sacrifice reform analysis" @@ -870,7 +870,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -892,7 +892,7 @@ "student_loan_plan" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Explore Education Statistics Table 6a, Higher education total", "survey": "Family Resources Survey 2024-25 and Student Loans Company borrower forecasts for England" @@ -914,7 +914,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -949,7 +949,7 @@ "required_mass_change_reason": "WAS wealth imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "90429a0d9fa3092257efc2809a35eb745e2ac8cf60bbed92c29da7fda07a05eb", + "source_manifest_sha256": "a89e2dad9d75768af47a394cab197e3115f18fe3a82efda12d8f22321359438e", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index 73ea7e2c7..2bdccd85e 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -229,11 +229,11 @@ }, { "kind": "map_columns", - "scope": "raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence)" + "scope": "raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence); Scottish water_and_sewerage_charges is the charge paid, (CWATAMT1 + CSEWAMT1) less the CTDISC/CT25D50D status discount, or where CTREB is 1 less the larger of that discount and the Water Charges Reduction Scheme's 35% (the full-reduction case), and CWATAMTD where CWATAMT1 is not positive (uk-data#499, microcosm#1095)" }, { "kind": "map_coded_amounts", - "scope": "region, tenure, accommodation, council tax band, benefit-code amount mappings; adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance" + "scope": "region, tenure, accommodation, council tax band, benefit-code amount mappings (Scotland's Adult and Child Disability Payment codes 117/118 and 121/122 into the PIP and DLA columns they replace; benefit recovery codes 69 and 70 unmapped); adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance" }, { "kind": "annualize_periodic_amounts", @@ -715,9 +715,9 @@ "ctband", "adulth == 1" ], - "donor_filter": "raw ctannual > 0", + "donor_filter": "raw ctreb != 1 and ctannual > 0", "missing": "raw ctannual < 0 or NaN", - "value": "Scottish-water-netted CTANNUAL" + "value": "council tax before council tax reduction: CTANNUAL net of the Scottish water and sewerage charges ((CWATAMT1 + CSEWAMT1) x 365.25/7, at 0.65 where CTREB is 1; CWATAMTD where CWATAMT1 is not positive), plus CTREBAMT x 365.25/7 where CTREB is 1 and CTREBAMT > 0; a CTREB 1 household without a positive CTREBAMT takes the larger of its netted CTANNUAL and its cell mean" } ], "outputs": [ @@ -726,7 +726,7 @@ "nonnegative_outputs": [ "council_tax" ], - "notes": "Re-reads raw househol.tab because spine council_tax_reported clips missing values. Scottish Water charges are netted before cell means; no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped." + "notes": "Re-reads raw househol.tab because spine council_tax_reported clips missing values. FRS 2024-25 CTANNUAL is the bill after discounts and council tax reduction, and the engine reads council_tax before the reduction, so a household reporting a reduction gets its CTREBAMT added back and the cells pool non-recipients only (uk-data#496/#499, microcosm#1095). Scottish water and sewerage charges are netted before cell means at the shares DWP's CTANNUAL carries (the gross charges in full for non-recipients, 65% for reduction recipients); no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped." }, { "stage": "frs_disability", @@ -1502,7 +1502,7 @@ "count_rule": "max(minimum_donors_per_band, ceil(published band taxpayers / maximum_donor_weight))", "weight_rule": "published band taxpayers / band donor count, equal within a band", "expected_band_count": 4, - "candidate_population": "raw FRS base channel adults aged 16 and over", + "candidate_population": "raw FRS base channel claimants and partners (is_uc_claimant) aged 16 and over", "candidate_order": "person_id ascending breaks equal draw keys", "draw": "weighted_without_replacement_identity_keyed: Efraimidis-Spirakis keys log(u) / (household weight x propensity) on stable_identity_uniforms(person_id, seed, salt:band); the largest keys are seated, one carrier per household, the highest band first", "propensity": "SPI 2022-23 FACT-weighted band share by region, sex and age band", @@ -1666,6 +1666,7 @@ "kind": "fit_weighted_qrf_stage1", "training_artifact_role": "qrf_donor", "recipient_minimum_age": 16, + "recipient_role_column": "is_uc_claimant", "rebase_income_to_build_period": true, "donor_income_period": 2022, "income_uprating_variables": { @@ -1865,7 +1866,7 @@ { "kind": "fit_weighted_qrf_stage2", "training_population": "uk_frs_raw_spine_base_support_channel", - "target_population": "spi_synthetic_support_channel", + "target_population": "spi_synthetic_support_channel claimants and partners (is_uc_claimant) aged 16 and over", "predictors": [ "age", "gender", @@ -1958,14 +1959,6 @@ "state_pension_age": "policyengine-uk gov.dwp.state_pension.age at the build instant", "receipt": "rows, weighted people and amounts removed per column and step" }, - { - "kind": "redraw_columns_from_fitted_qrf", - "fit": "stage1", - "columns": [ - "dividend_income" - ], - "rows": "base_support_channel" - }, { "kind": "materialize_hmrc_income_bands_fail_closed", "artifact_role": "published_fact_surface", @@ -2302,7 +2295,7 @@ "hmrc_spi_unemployment_benefit_income", "hmrc_spi_incapacity_benefit_income" ], - "notes": "Runs the SPI-trained income QRFs on the raw-spine support channel, initializes FRS charity columns to zero, trains FRS-only stage 2 before redrawing base-channel dividends, and emits a sidecar-only 208-fact replay report for the spine path." + "notes": "Runs the SPI-trained income QRFs on the raw-spine support channel, drawing for its claimants and partners aged 16 and over so dependants aged 16 to 19 keep their FRS twin's values (uk-data#504, microcosm#1095), initializes FRS charity columns to zero, trains FRS-only stage 2 on the FRS rows' reported values, leaves every FRS-channel income as reported (no base-channel redraw of dividends; uk-data#498, microcosm#1095), and emits a sidecar-only 208-fact replay report for the spine path." }, { "stage": "spi_housing_shell", @@ -2437,11 +2430,14 @@ "tenure_code": "Ten1R8", "private_rent_code": "DVPriRntR8", "main_residence_value": "DVhvalueR8", - "other_residential_property_value": "DVHseValR8_sum", "non_residential_property_value": "DVBlDValR8_sum", "savings": "DVSaValR8_aggr", "num_vehicles": "vcarnr8", - "weight": "R8xshhwgt" + "weight": "R8xshhwgt", + "num_adults": "NumAdultR8", + "num_children": "NumChildR8", + "council_tax": "DVCTaxAmtAnnualR8", + "rental_income": "DVNetRentAmtAnnualR8_aggr" }, "derived": { "private_pension_wealth": "totalpenr8_aggr - dvvaldbt_scaper8_aggr", @@ -2451,7 +2447,8 @@ "student_loan_balance": "Tot_LosR8_aggr - Tot_los_exc_SLCR8_aggr", "consumer_debt": "max(HFINWR8_SUM - HFINWNTR8_exSLC_Sum, 0)", "tenure_category": "Ten1R8 1 owned_outright; 2 or 3 owned_with_mortgage; 4 or 5 private_rent when DVPriRntR8 == 1, otherwise social_rent; any other code private_rent, counted in the receipt", - "other_property_value": "DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative", + "other_residential_property_value": "DVHseValR8_sum + DVBltValR8_sum (houses other than the main residence plus buy-to-let property)", + "other_property_value": "DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBltValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative", "other_financial_assets": "HFINWR8_SUM - (DVSaValR8_aggr + DVCISAVR8_aggr + corporate_wealth), refused when negative", "is_renting": "DVPriRntR8 == 1", "region": "GORR8 via incumbent REGIONS map" @@ -2461,8 +2458,6 @@ "kind": "materialize_rules_engine_predictors", "predictors": [ "household_net_income", - "num_adults", - "num_children", "private_pension_income", "employment_income", "self_employment_income", @@ -2483,6 +2478,7 @@ "employment_income", "self_employment_income", "capital_income", + "rental_income", "num_bedrooms", "council_tax", "tenure_owned_with_mortgage", @@ -2640,7 +2636,7 @@ "mortgage_debt", "consumer_debt" ], - "notes": "Ports incumbent WAS round-8 wealth imputation with signed E5 differences: exact lower-case column matching replaces the fuzzy r/w fallback; cash ISA uses DVCISAVR8_aggr and stocks-and-shares ISA uses DVIISAVR8_aggr; private pension wealth (WAS total private pension wealth less the current defined-benefit component; DB-type components at the SCAPE rate, money-purchase components at reported fund values) is drawn as its own output private_pension_wealth and no longer folded into corporate_wealth, which keeps only the share-like holdings - pension rights are disregarded capital in every means test (UC Regs 2013 Sch 10 para 10 and the HB/JSA/ESA/IS/SPC parallels; uk-data#452) - and the downstream chain segment conditions on both components; each chain segment starts its own fit and draw RNG streams from a child seed derived deterministically from the declared seed (start_chain respawns from the model seed on every call, so one shared model coupled the k-th target of every segment); corporate_wealth folds stocks-and-shares ISA after drawing corporate_wealth_excl_isa; recipient Northern Ireland regions are mapped to Wales for prediction only; student_loan_balance is allocated by household id rather than the incumbent positional off-by-one. Tenure enters every chain segment as one four-way category built the same way on both sides (microcosm#1063): the donor's from Ten1R8 and DVPriRntR8 (owned outright; buying with a mortgage or part rent, part mortgage; rented or rent-free from a private landlord; rented from a council or housing association), the recipient's from the frame's tenure_type (council and housing association together), so the stage reads no engine tenure formula. Two columns are structural in tenure and are fitted and drawn inside their stratum only, zero by rule elsewhere: main_residence_value on the owner tenures (every WAS owner has a positive value and no renter has one) and main_residence_mortgage (TotMortR8) on the mortgaged tenure. mortgage_debt is HMortGR8, all of the household's mortgages, and is derived as the main-residence mortgage plus the mortgages on other property (other_mortgage, HMortGR8 less TotMortR8 on the donor: buy-to-let, second homes and the rest), which are held on every tenure and drawn without a stratum, so an outright owner's or a renter's buy-to-let keeps its mortgage beside the property it is secured on (OthMortR8_sum is read for the receipt only); the donor's conditioning copy carries the same rule, so consumer_debt is fitted on values recipients can hold. Totals are not drawn: property_wealth is the sum of land, the main residence, other houses, buildings and a drawn remainder (buy-to-let, overseas and other property), gross_financial_wealth is savings, the cash ISA, the share-like holdings and a drawn remainder, and net_financial_wealth is gross less consumer debt and the student loan balance - identities the pinned tab satisfies on every row and the cleaning step refuses a donor that breaks. A sum of donor-valued components that leaves the donor's range for the total gives up the excess from the remainder first, and the receipt counts the rows. Eight chain segments, each with its own child seed: land; the main residence; the other property components; pension and share-like wealth; the financial components, vehicles and the student loan balance; the main-residence mortgage; the other mortgages; consumer debt. HFINWNTR8_exSLC_Sum is net financial wealth excluding student loans, so gross less it is the non-student-loan financial liabilities; UKDS SN 7215 documentation is the codebook. Engine predictors materialize at their native entity and person/benunit values are summed to household, reproducing the incumbent map_to=household semantics; region is one-hot encoded jointly across donor and recipient (the incumbent's dummy encoding), with unmapped donor GOR codes becoming all-zero dummy rows. The WAS and FRS predictor definitions are not fully like-for-like and are ported as-is; raw WAS missing values are blanket-filled with zero; UKDS negative sentinel codes (-9/-8/-7/-6) are recoded to zero for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8's -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded." + "notes": "Ports incumbent WAS round-8 wealth imputation with signed E5 differences: exact lower-case column matching replaces the fuzzy r/w fallback; cash ISA uses DVCISAVR8_aggr and stocks-and-shares ISA uses DVIISAVR8_aggr; private pension wealth (WAS total private pension wealth less the current defined-benefit component; DB-type components at the SCAPE rate, money-purchase components at reported fund values) is drawn as its own output private_pension_wealth and no longer folded into corporate_wealth, which keeps only the share-like holdings - pension rights are disregarded capital in every means test (UC Regs 2013 Sch 10 para 10 and the HB/JSA/ESA/IS/SPC parallels; uk-data#452) - and the downstream chain segment conditions on both components; each chain segment starts its own fit and draw RNG streams from a child seed derived deterministically from the declared seed (start_chain respawns from the model seed on every call, so one shared model coupled the k-th target of every segment); corporate_wealth folds stocks-and-shares ISA after drawing corporate_wealth_excl_isa; recipient Northern Ireland regions are mapped to Wales for prediction only; student_loan_balance is allocated by household id rather than the incumbent positional off-by-one. Tenure enters every chain segment as one four-way category built the same way on both sides (microcosm#1063): the donor's from Ten1R8 and DVPriRntR8 (owned outright; buying with a mortgage or part rent, part mortgage; rented or rent-free from a private landlord; rented from a council or housing association), the recipient's from the frame's tenure_type (council and housing association together), so the stage reads no engine tenure formula. Two columns are structural in tenure and are fitted and drawn inside their stratum only, zero by rule elsewhere: main_residence_value on the owner tenures (every WAS owner has a positive value and no renter has one) and main_residence_mortgage (TotMortR8) on the mortgaged tenure. mortgage_debt is HMortGR8, all of the household's mortgages, and is derived as the main-residence mortgage plus the mortgages on other property (other_mortgage, HMortGR8 less TotMortR8 on the donor: buy-to-let, second homes and the rest), which are held on every tenure and drawn without a stratum, so an outright owner's or a renter's buy-to-let keeps its mortgage beside the property it is secured on (OthMortR8_sum is read for the receipt only); the donor's conditioning copy carries the same rule, so consumer_debt is fitted on values recipients can hold. Totals are not drawn: property_wealth is the sum of land, the main residence, other houses, buildings and a drawn remainder (buy-to-let, overseas and other property), gross_financial_wealth is savings, the cash ISA, the share-like holdings and a drawn remainder, and net_financial_wealth is gross less consumer debt and the student loan balance - identities the pinned tab satisfies on every row and the cleaning step refuses a donor that breaks. A sum of donor-valued components that leaves the donor's range for the total gives up the excess from the remainder first, and the receipt counts the rows. Eight chain segments, each with its own child seed: land; the main residence; the other property components; pension and share-like wealth; the financial components, vehicles and the student loan balance; the main-residence mortgage; the other mortgages; consumer debt. HFINWNTR8_exSLC_Sum is net financial wealth excluding student loans, so gross less it is the non-student-loan financial liabilities; UKDS SN 7215 documentation is the codebook. Engine predictors materialize at their native entity and person/benunit values are summed to household, reproducing the incumbent map_to=household semantics; region is one-hot encoded jointly across donor and recipient (the incumbent's dummy encoding), with unmapped donor GOR codes becoming all-zero dummy rows. The WAS and FRS predictor definitions are not fully like-for-like and are ported as-is; raw WAS missing values are blanket-filled with zero; UKDS negative sentinel codes (-9/-8/-7/-6) are recoded to zero for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8's -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded. The recipient council_tax predictor is the bill the household pays, council_tax less council_tax_rebate, the quantity the WAS donor records, since the spine's council_tax is the liability before council tax reduction (uk-data#496/#499, microcosm#1095). The donor council_tax is DVCTaxAmtAnnualR8, the annual amount paid (CTAmtR8 is one instalment), its children are NumChildR8 (NumCh18R8 overlaps NumAdultR8), and the recipient adults and children are the household's FRS claimants and partners and its other members (is_uc_claimant), which together make the household size on both sides; rental_income is the donor's net rent DVNetRentAmtAnnualR8_aggr against the household's property_income (uk-data#486/#495, microcosm#1095)." }, { "stage": "was_lisa", @@ -3933,11 +3929,13 @@ { "kind": "materialize_rules_engine_predictors", "predictors": [ - "is_adult", - "is_child", "is_SP_age", "household_net_income" - ] + ], + "derived_predictors": { + "is_adult": "count of household members with is_uc_claimant (FRS claimants and partners)", + "is_child": "count of household members without is_uc_claimant (dependent children)" + } }, { "kind": "fit_weighted_qrf", @@ -3970,7 +3968,7 @@ "full_rate_vat_expenditure_rate" ], "nonnegative_outputs": [], - "notes": "Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth." + "notes": "Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth. The recipient is_adult and is_child counts are the household's FRS claimants and partners and its other members (is_uc_claimant), as the donor's adults and childs count adults and dependent children, not the engine's age-18 split (uk-data#486, microcosm#1095)." }, { "stage": "etb_services", @@ -4068,8 +4066,6 @@ { "kind": "materialize_rules_engine_predictors", "predictors": [ - "is_adult", - "is_child", "is_SP_age", "dla", "pip", @@ -4077,6 +4073,8 @@ "current_education" ], "derived_predictors": { + "is_adult": "count of household members with is_uc_claimant (FRS claimants and partners)", + "is_child": "count of household members without is_uc_claimant (dependent children)", "count_primary_education": "current_education == PRIMARY", "count_secondary_education": "current_education == LOWER_SECONDARY", "count_further_education": "current_education in (UPPER_SECONDARY, TERTIARY)" @@ -4393,7 +4391,7 @@ "nhs_admitted_patient_spending", "nhs_outpatient_spending" ], - "notes": "Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine's CPI index, rail support by ORR table 7270's own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame's journeys (microcosm#930; the" + "notes": "Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine's CPI index, rail support by ORR table 7270's own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame's journeys (microcosm#930; the #890 rake to the published net support retired on María's ruling of 2026-09-23): per household, the published concessionary travel reimbursement per concessionary boarding times its eligible persons' boardings plus the rest of the published net support per boarding times every boarding, boardings being the nts_bus_travel trips times the fare pricing's boardings per resident trip, for London and England outside London (DfT BUS05bi and BUS01) and Scotland (Scottish Transport Statistics components and journeys); Wales (no published boardings) and Northern Ireland (the NITHC accounts carry bus and rail jointly) keep the chain's raw draw, clipped to donor support; the published totals stay bound as calibration targets and now measure the priced quantity, computes rail_usage from the 2024 fare index, and allocates NHS visits/spending to persons using the signed half-open age bands with the donor table's native 85-89, 90-94 and 95+ top bands (the former 85+ fold-in was retired once age_tail moved ahead of this stage and recipients could populate those bands). The year-max donor filter resolves to 2023 on the pinned tab (the file labels financial year ending 2024 as year 2023), so the services training year coincides with the VAT training year and the fare-index year - the incumbent's apparent three-way year mismatch is vacuous on this vintage. The recipient is_adult and is_child counts are the household's FRS claimants and partners and its other members (is_uc_claimant), as the donor's adults and childs count adults and dependent children, not the engine's age-18 split (uk-data#486, microcosm#1095)." }, { "stage": "uc_reporter_redraw", @@ -4465,6 +4463,96 @@ ], "notes": "Runs after the person-grain SPI income chain and before UC capital coherence. One temporary engine simulation screens both FRS and SPI benefit units to a positive pre-take-up award using FRS-carried capital AND at least one non-child member (uc_maximum_amount pays qualifying-young-person-only units mechanically), and materializes the UC child and state-pension-age flags; engine-known values are consumed only. The consumed is_uc_couple predictor counts two retained FRS claimant/partner roles, independently of legal is_married; older dependent children do not become partners. A benefit-unit RegimeGatedQRF fitted on the screened base domain draws the screened SPI domain (rows); the rewrite domain (rewrite_rows) is the whole SPI channel, so screen-failing SPI units are zeroed. Each positive amount lands on one deterministic adult claimant; base-FRS rows remain byte-unchanged; an empty screened SPI domain refuses." }, + { + "stage": "spi_benefit_coherence", + "survey": "Family Resources Survey 2024-25", + "source": "Family Resources Survey 2024-25 benefit reports carried through the SPI support channel, with the UK take-up contract's Universal Credit rate.", + "grain": "person+benunit", + "artifacts": [], + "operations": [ + { + "kind": "zero_spi_channel_reports", + "rows": "spi_synthetic_support_channel", + "columns": [ + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported" + ], + "reason": "award needs an existing legacy claim, an out-of-work test, or a claim the copied household's new incomes cannot carry" + }, + { + "kind": "restore_spi_channel_reports_from_source", + "rows": "spi_synthetic_support_channel", + "columns": [ + "iidb_reported", + "afcs_reported", + "bsp_reported" + ], + "linkage": "person_source_id -> FRS-channel person_id", + "reason": "follows an injury, service or a death, not income" + }, + { + "kind": "derive", + "scope": "disability categories and flags re-derived on SPI-channel rows from the final reports with the frs_disability rule at its declared year; the categories, which read only AA, DLA and PIP, asserted unchanged" + }, + { + "kind": "derive", + "output": "receives_benefits_in_own_right", + "formula": "universal_credit_reported + jsa_contrib_reported + jsa_income_reported + esa_contrib_reported + esa_income_reported > 0 (frs_education), SPI-channel rows; FRS rows asserted unchanged" + }, + { + "kind": "aggregate_person_to_benunit", + "method": "any_positive", + "consumed_only": true, + "aggregates": { + "universal_credit_reported_anchor": "universal_credit_reported" + } + }, + { + "kind": "aggregate_person_to_benunit", + "method": "any_adult_under_state_pension_age", + "consumed_only": true, + "aggregates": { + "uc_age_eligible": "age" + } + }, + { + "kind": "assign_binary_with_anchored_residual", + "output": "would_claim_uc", + "draw": "would_claim_uc", + "rate_key": "universal_credit", + "anchor": "universal_credit_reported_anchor", + "population": "uc_age_eligible", + "seed": 0, + "rows": "spi_synthetic_support_channel" + } + ], + "outputs": [], + "rewrites": [ + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported", + "iidb_reported", + "afcs_reported", + "bsp_reported", + "is_disabled_for_benefits", + "is_enhanced_disabled_for_benefits", + "is_severely_disabled_for_benefits", + "receives_benefits_in_own_right", + "would_claim_uc" + ], + "notes": "Runs on SPI-channel rows after uc_reporter_redraw, the last writer of Universal Credit reports, and before uc_capital_coherence and the Pension Credit and Child Benefit take-up stages (microcosm#1095, uk-data#514). The stage-2 forests of hmrc_spi_income_spine re-impute each SPI adult's benefit reports from age, gender, region and the new incomes, with nothing of the benefit unit's entitlement or claim history. This stage zeroes the SPI rows' contributory and income-based JSA, income-related ESA, Income Support, Working and Child Tax Credit, Severe Disablement Allowance and Sure Start Maternity Grant reports, whose award needs an existing legacy claim, an out-of-work test, or a claim the copied household's new incomes cannot carry (policyengine-uk pays income-related ESA as reported behind a capital test alone); restores Industrial Injuries Disablement Benefit, the Armed Forces Compensation Scheme and bereavement support from the FRS twin (person_source_id), since they follow an injury, service or a death; re-derives the disability flags (the categories, which read only AA, DLA and PIP, are asserted unchanged) and receives_benefits_in_own_right from the final reports; and redraws would_claim_uc for SPI benefit units as frs_take_up draws it for FRS units: a unit with a Universal Credit reporter claims, and the other units in the Universal Credit age population claim as the residual of the contract's universal_credit rate on draws keyed on the SPI unit's own identity. Contributory ESA, PIP, DLA, AA, Carer's Allowance, State Pension and Winter Fuel Payment keep their draws, and FRS rows are never modified; contributory ESA is open to new claims and not income-tested, and the incapacity it needs follows the person, whose health and disability reports the SPI copy keeps." + }, { "stage": "uc_capital_coherence", "survey": "Family Resources Survey 2024-25", @@ -4483,8 +4571,24 @@ { "kind": "redraw_spi_reporter_capital", "output": "frs_benunit_capital", - "rows": "spi_channel_post_fill_reporters", - "donor_rows": "base_frs_reporters_with_available_capital", + "rows": "spi_channel", + "donor_rows": "base_frs_with_available_capital", + "reporter_status": "universal_credit_reported_anchor", + "investment_income": "savings_interest_income + dividend_income + other_investment_income, summed over benefit-unit members", + "investment_income_band_edges": [ + 0.0, + 240.0, + 640.0, + 2000.0, + 8000.0 + ], + "minimum_cell_donors": 20, + "coarsening": [ + "merge dependent-children bands", + "drop couple status", + "merge adjacent investment-income bands", + "reporter status only" + ], "dependent_children_bands": [ "0", "1", @@ -4513,7 +4617,7 @@ "frs_benunit_capital", "would_claim_uc" ], - "notes": "Runs after the last universal_credit_reported writer and before CGT cloning. Redraws only SPI post-fill reporters from weighted base-FRS reporter capital within dependent-children band by is_uc_couple cells (two retained FRS claimant/partner roles, independently of legal is_married), then applies the monotone reported-UC OR refresh." + "notes": "Runs after the last universal_credit_reported writer and before CGT cloning. Redraws every SPI benefit unit's capital, since the channel's incomes are SPI draws and the copied FRS answer no longer belongs to the unit (uk-data#495, microcosm#1095), from weighted base-FRS units with available capital in cells of UC reporter status by financial investment income band (interest, dividends and other investment income; property income is excluded because TOTCAPB4 counts accounts and assets) by is_uc_couple (two retained FRS claimant/partner roles, independently of legal is_married) by dependent-children band. A cell with fewer than 20 donors widens in the declared coarsening order, and reporter status is never coarsened. It then applies the monotone reported-UC OR refresh." }, { "stage": "pension_credit_take_up", diff --git a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml index 83b46e874..abc098bf4 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -368,9 +368,9 @@ stages: person_table: adult union child household_sort: set_index('household_id').sort_index() before positional household reads - kind: map_columns - scope: 'raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence)' + scope: 'raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence); Scottish water_and_sewerage_charges is the charge paid, (CWATAMT1 + CSEWAMT1) less the CTDISC/CT25D50D status discount, or where CTREB is 1 less the larger of that discount and the Water Charges Reduction Scheme''s 35% (the full-reduction case), and CWATAMTD where CWATAMT1 is not positive (uk-data#499, microcosm#1095)' - kind: map_coded_amounts - scope: region, tenure, accommodation, council tax band, benefit-code amount mappings; adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance + scope: region, tenure, accommodation, council tax band, benefit-code amount mappings (Scotland's Adult and Child Disability Payment codes 117/118 and 121/122 into the PIP and DLA columns they replace; benefit recovery codes 69 and 70 unmapped); adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance - kind: annualize_periodic_amounts weeks_in_year: 52.17857142857143 outputs: @@ -715,14 +715,14 @@ stages: - gvtregno - ctband - adulth == 1 - donor_filter: raw ctannual > 0 + donor_filter: raw ctreb != 1 and ctannual > 0 missing: raw ctannual < 0 or NaN - value: Scottish-water-netted CTANNUAL + value: 'council tax before council tax reduction: CTANNUAL net of the Scottish water and sewerage charges ((CWATAMT1 + CSEWAMT1) x 365.25/7, at 0.65 where CTREB is 1; CWATAMTD where CWATAMT1 is not positive), plus CTREBAMT x 365.25/7 where CTREB is 1 and CTREBAMT > 0; a CTREB 1 household without a positive CTREBAMT takes the larger of its netted CTANNUAL and its cell mean' outputs: - council_tax nonnegative_outputs: - council_tax - notes: Re-reads raw househol.tab because spine council_tax_reported clips missing values. Scottish Water charges are netted before cell means; no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped. + notes: Re-reads raw househol.tab because spine council_tax_reported clips missing values. FRS 2024-25 CTANNUAL is the bill after discounts and council tax reduction, and the engine reads council_tax before the reduction, so a household reporting a reduction gets its CTREBAMT added back and the cells pool non-recipients only (uk-data#496/#499, microcosm#1095). Scottish water and sewerage charges are netted before cell means at the shares DWP's CTANNUAL carries (the gross charges in full for non-recipients, 65% for reduction recipients); no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped. - stage: frs_disability survey: Family Resources Survey 2024-25 source: Department for Work and Pensions Family Resources Survey 2024-25, UK Data Service SN 9563, DOI 10.5255/UKDA-SN-9563-1; local licensed 2024_25 tabs. plus policyengine-uk DWP parameters. @@ -1301,7 +1301,7 @@ stages: count_rule: max(minimum_donors_per_band, ceil(published band taxpayers / maximum_donor_weight)) weight_rule: published band taxpayers / band donor count, equal within a band expected_band_count: 4 - candidate_population: raw FRS base channel adults aged 16 and over + candidate_population: raw FRS base channel claimants and partners (is_uc_claimant) aged 16 and over candidate_order: person_id ascending breaks equal draw keys draw: 'weighted_without_replacement_identity_keyed: Efraimidis-Spirakis keys log(u) / (household weight x propensity) on stable_identity_uniforms(person_id, seed, salt:band); the largest keys are seated, one carrier per household, the highest band first' propensity: SPI 2022-23 FACT-weighted band share by region, sex and age band @@ -1440,6 +1440,7 @@ stages: - kind: fit_weighted_qrf_stage1 training_artifact_role: qrf_donor recipient_minimum_age: 16 + recipient_role_column: is_uc_claimant rebase_income_to_build_period: true donor_income_period: 2022 income_uprating_variables: @@ -1600,7 +1601,7 @@ stages: seed: 44 - kind: fit_weighted_qrf_stage2 training_population: uk_frs_raw_spine_base_support_channel - target_population: spi_synthetic_support_channel + target_population: spi_synthetic_support_channel claimants and partners (is_uc_claimant) aged 16 and over predictors: - age - gender @@ -1680,11 +1681,6 @@ stages: - state_pension_reported state_pension_age: policyengine-uk gov.dwp.state_pension.age at the build instant receipt: rows, weighted people and amounts removed per column and step - - kind: redraw_columns_from_fitted_qrf - fit: stage1 - columns: - - dividend_income - rows: base_support_channel - kind: materialize_hmrc_income_bands_fail_closed artifact_role: published_fact_surface mapped_build_period: 2024 @@ -1964,7 +1960,7 @@ stages: - hmrc_spi_pay - hmrc_spi_unemployment_benefit_income - hmrc_spi_incapacity_benefit_income - notes: Runs the SPI-trained income QRFs on the raw-spine support channel, initializes FRS charity columns to zero, trains FRS-only stage 2 before redrawing base-channel dividends, and emits a sidecar-only 208-fact replay report for the spine path. + notes: Runs the SPI-trained income QRFs on the raw-spine support channel, drawing for its claimants and partners aged 16 and over so dependants aged 16 to 19 keep their FRS twin's values (uk-data#504, microcosm#1095), initializes FRS charity columns to zero, trains FRS-only stage 2 on the FRS rows' reported values, leaves every FRS-channel income as reported (no base-channel redraw of dividends; uk-data#498, microcosm#1095), and emits a sidecar-only 208-fact replay report for the spine path. - stage: spi_housing_shell survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 base households' housing (tenure, dwelling type, bedrooms, council tax, housing costs and the housing-linked benefit reports), imputed onto the SPI support households from their own region, composition and post-SPI incomes. @@ -2079,11 +2075,14 @@ stages: tenure_code: Ten1R8 private_rent_code: DVPriRntR8 main_residence_value: DVhvalueR8 - other_residential_property_value: DVHseValR8_sum non_residential_property_value: DVBlDValR8_sum savings: DVSaValR8_aggr num_vehicles: vcarnr8 weight: R8xshhwgt + num_adults: NumAdultR8 + num_children: NumChildR8 + council_tax: DVCTaxAmtAnnualR8 + rental_income: DVNetRentAmtAnnualR8_aggr derived: private_pension_wealth: totalpenr8_aggr - dvvaldbt_scaper8_aggr corporate_wealth_excl_isa: DVFESHARESR8_aggr + DVFShUKVR8_aggr + DVFCollVR8_aggr @@ -2092,15 +2091,14 @@ stages: student_loan_balance: Tot_LosR8_aggr - Tot_los_exc_SLCR8_aggr consumer_debt: max(HFINWR8_SUM - HFINWNTR8_exSLC_Sum, 0) tenure_category: 'Ten1R8 1 owned_outright; 2 or 3 owned_with_mortgage; 4 or 5 private_rent when DVPriRntR8 == 1, otherwise social_rent; any other code private_rent, counted in the receipt' - other_property_value: DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative + other_residential_property_value: DVHseValR8_sum + DVBltValR8_sum (houses other than the main residence plus buy-to-let property) + other_property_value: DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBltValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative other_financial_assets: HFINWR8_SUM - (DVSaValR8_aggr + DVCISAVR8_aggr + corporate_wealth), refused when negative is_renting: DVPriRntR8 == 1 region: GORR8 via incumbent REGIONS map - kind: materialize_rules_engine_predictors predictors: - household_net_income - - num_adults - - num_children - private_pension_income - employment_income - self_employment_income @@ -2118,6 +2116,7 @@ stages: - employment_income - self_employment_income - capital_income + - rental_income - num_bedrooms - council_tax - tenure_owned_with_mortgage @@ -2246,7 +2245,7 @@ stages: - mortgage_debt - consumer_debt notes: 'Ports incumbent WAS round-8 wealth imputation with signed E5 differences: exact lower-case column matching replaces the fuzzy r/w fallback; cash ISA uses DVCISAVR8_aggr and stocks-and-shares ISA uses DVIISAVR8_aggr; private pension wealth (WAS total private pension wealth less the current defined-benefit component; DB-type components at the SCAPE rate, money-purchase components at reported fund values) is drawn as its own output private_pension_wealth and no longer folded into corporate_wealth, which keeps only the share-like holdings - pension rights are disregarded capital in every means test (UC Regs 2013 Sch 10 para 10 and the HB/JSA/ESA/IS/SPC parallels; uk-data#452) - and the downstream chain segment conditions on both components; each chain segment starts its own fit and draw RNG streams from a child seed derived deterministically from the declared seed (start_chain respawns from the model seed on every call, so one shared model coupled the k-th target of every segment); corporate_wealth folds stocks-and-shares ISA after drawing corporate_wealth_excl_isa; recipient Northern Ireland regions are mapped to Wales for prediction only; student_loan_balance is allocated by household id rather than the incumbent positional off-by-one. Tenure enters every chain segment as one four-way category built the same way on both sides (microcosm#1063): the donor''s from Ten1R8 and DVPriRntR8 (owned outright; buying with a mortgage or part rent, part mortgage; rented or rent-free from a private landlord; rented from a council or housing association), the recipient''s from the frame''s tenure_type (council and housing association together), so the stage reads no engine tenure formula. Two columns are structural in tenure and are fitted and drawn inside their stratum only, zero by rule elsewhere: main_residence_value on the owner tenures (every WAS owner has a positive value and no renter has one) and main_residence_mortgage (TotMortR8) on the mortgaged tenure. mortgage_debt is HMortGR8, all of the household''s mortgages, and is derived as the main-residence mortgage plus the mortgages on other property (other_mortgage, HMortGR8 less TotMortR8 on the donor: buy-to-let, second homes and the rest), which are held on every tenure and drawn without a stratum, so an outright owner''s or a renter''s buy-to-let keeps its mortgage beside the property it is secured on (OthMortR8_sum is read for the receipt only); the donor''s conditioning copy carries the same rule, so consumer_debt is fitted on values recipients can hold. Totals are not drawn: property_wealth is the sum of land, the main residence, other houses, buildings and a drawn remainder (buy-to-let, overseas and other property), gross_financial_wealth is savings, the cash ISA, the share-like holdings and a drawn remainder, and net_financial_wealth is gross less consumer debt and the student loan balance - identities the pinned tab satisfies on every row and the cleaning step refuses a donor that breaks. A sum of donor-valued components that leaves the donor''s range for the total gives up the excess from the remainder first, and the receipt counts the rows. Eight chain segments, each with its own child seed: land; the main residence; the other property components; pension and share-like wealth; the financial components, vehicles and the student loan balance; the main-residence mortgage; the other mortgages; consumer debt. HFINWNTR8_exSLC_Sum is net financial wealth excluding student loans, so gross less it is the non-student-loan financial liabilities; UKDS SN 7215 documentation is the codebook. Engine predictors materialize at their native entity and person/benunit values are summed to household, reproducing the incumbent map_to=household semantics; region is one-hot encoded jointly across donor and recipient (the incumbent''s dummy encoding), with unmapped donor GOR codes becoming all-zero dummy rows. The WAS and FRS predictor definitions are not fully like-for-like and are ported as-is; raw WAS missing values are blanket-filled with zero; UKDS negative sentinel codes (-9/-8/-7/-6) are recoded to zero - for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8''s -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded.' + for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8''s -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded. The recipient council_tax predictor is the bill the household pays, council_tax less council_tax_rebate, the quantity the WAS donor records, since the spine''s council_tax is the liability before council tax reduction (uk-data#496/#499, microcosm#1095). The donor council_tax is DVCTaxAmtAnnualR8, the annual amount paid (CTAmtR8 is one instalment), its children are NumChildR8 (NumCh18R8 overlaps NumAdultR8), and the recipient adults and children are the household''s FRS claimants and partners and its other members (is_uc_claimant), which together make the household size on both sides; rental_income is the donor''s net rent DVNetRentAmtAnnualR8_aggr against the household''s property_income (uk-data#486/#495, microcosm#1095).' - stage: was_lisa survey: Wealth and Assets Survey round 8 source: Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain). @@ -3228,10 +3227,11 @@ stages: fail_loud_on_missing_rate: true - kind: materialize_rules_engine_predictors predictors: - - is_adult - - is_child - is_SP_age - household_net_income + derived_predictors: + is_adult: count of household members with is_uc_claimant (FRS claimants and partners) + is_child: count of household members without is_uc_claimant (dependent children) - kind: fit_weighted_qrf predictors: - is_adult @@ -3253,7 +3253,7 @@ stages: outputs: - full_rate_vat_expenditure_rate nonnegative_outputs: [] - notes: 'Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth.' + notes: 'Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth. The recipient is_adult and is_child counts are the household''s FRS claimants and partners and its other members (is_uc_claimant), as the donor''s adults and childs count adults and dependent children, not the engine''s age-18 split (uk-data#486, microcosm#1095).' - stage: etb_services survey: Effects of Taxes and Benefits 1977-2024 and NHS age-gender public table source: UK Data Service SN 8856 Effects of Taxes and Benefits household tab, DfT rail fare index, and public NHS activity/cost table. @@ -3323,14 +3323,14 @@ stages: geography_id: E92000001 - kind: materialize_rules_engine_predictors predictors: - - is_adult - - is_child - is_SP_age - dla - pip - hbai_household_net_income - current_education derived_predictors: + is_adult: count of household members with is_uc_claimant (FRS claimants and partners) + is_child: count of household members without is_uc_claimant (dependent children) count_primary_education: current_education == PRIMARY count_secondary_education: current_education == LOWER_SECONDARY count_further_education: current_education in (UPPER_SECONDARY, TERTIARY) @@ -3573,7 +3573,7 @@ stages: - nhs_a_and_e_spending - nhs_admitted_patient_spending - nhs_outpatient_spending - notes: Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine's CPI index, rail support by ORR table 7270's own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame's journeys (microcosm#930; the #890 rake to the published net support retired on María's ruling of 2026-09-23): per household, the published concessionary travel reimbursement per concessionary boarding times its eligible persons' boardings plus the rest of the published net support per boarding times every boarding, boardings being the nts_bus_travel trips times the fare pricing's boardings per resident trip, for London and England outside London (DfT BUS05bi and BUS01) and Scotland (Scottish Transport Statistics components and journeys); Wales (no published boardings) and Northern Ireland (the NITHC accounts carry bus and rail jointly) keep the chain's raw draw, clipped to donor support; the published totals stay bound as calibration targets and now measure the priced quantity, computes rail_usage from the 2024 fare index, and allocates NHS visits/spending to persons using the signed half-open age bands with the donor table's native 85-89, 90-94 and 95+ top bands (the former 85+ fold-in was retired once age_tail moved ahead of this stage and recipients could populate those bands). The year-max donor filter resolves to 2023 on the pinned tab (the file labels financial year ending 2024 as year 2023), so the services training year coincides with the VAT training year and the fare-index year - the incumbent's apparent three-way year mismatch is vacuous on this vintage. + notes: 'Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine''s CPI index, rail support by ORR table 7270''s own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame''s journeys (microcosm#930; the #890 rake to the published net support retired on María''s ruling of 2026-09-23): per household, the published concessionary travel reimbursement per concessionary boarding times its eligible persons'' boardings plus the rest of the published net support per boarding times every boarding, boardings being the nts_bus_travel trips times the fare pricing''s boardings per resident trip, for London and England outside London (DfT BUS05bi and BUS01) and Scotland (Scottish Transport Statistics components and journeys); Wales (no published boardings) and Northern Ireland (the NITHC accounts carry bus and rail jointly) keep the chain''s raw draw, clipped to donor support; the published totals stay bound as calibration targets and now measure the priced quantity, computes rail_usage from the 2024 fare index, and allocates NHS visits/spending to persons using the signed half-open age bands with the donor table''s native 85-89, 90-94 and 95+ top bands (the former 85+ fold-in was retired once age_tail moved ahead of this stage and recipients could populate those bands). The year-max donor filter resolves to 2023 on the pinned tab (the file labels financial year ending 2024 as year 2023), so the services training year coincides with the VAT training year and the fare-index year - the incumbent''s apparent three-way year mismatch is vacuous on this vintage. The recipient is_adult and is_child counts are the household''s FRS claimants and partners and its other members (is_uc_claimant), as the donor''s adults and childs count adults and dependent children, not the engine''s age-18 split (uk-data#486, microcosm#1095).' - stage: uc_reporter_redraw survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 reported Universal Credit amounts, conditioned on benefit-unit composition and post-SPI incomes with PolicyEngine-UK eligibility inputs. @@ -3627,6 +3627,74 @@ stages: rewrites: - universal_credit_reported notes: Runs after the person-grain SPI income chain and before UC capital coherence. One temporary engine simulation screens both FRS and SPI benefit units to a positive pre-take-up award using FRS-carried capital AND at least one non-child member (uc_maximum_amount pays qualifying-young-person-only units mechanically), and materializes the UC child and state-pension-age flags; engine-known values are consumed only. The consumed is_uc_couple predictor counts two retained FRS claimant/partner roles, independently of legal is_married; older dependent children do not become partners. A benefit-unit RegimeGatedQRF fitted on the screened base domain draws the screened SPI domain (rows); the rewrite domain (rewrite_rows) is the whole SPI channel, so screen-failing SPI units are zeroed. Each positive amount lands on one deterministic adult claimant; base-FRS rows remain byte-unchanged; an empty screened SPI domain refuses. +- stage: spi_benefit_coherence + survey: Family Resources Survey 2024-25 + source: Family Resources Survey 2024-25 benefit reports carried through the SPI support channel, with the UK take-up contract's Universal Credit rate. + grain: person+benunit + artifacts: [] + operations: + - kind: zero_spi_channel_reports + rows: spi_synthetic_support_channel + columns: + - jsa_contrib_reported + - jsa_income_reported + - esa_income_reported + - income_support_reported + - working_tax_credit_reported + - child_tax_credit_reported + - sda_reported + - ssmg_reported + reason: award needs an existing legacy claim, an out-of-work test, or a claim the copied household's new incomes cannot carry + - kind: restore_spi_channel_reports_from_source + rows: spi_synthetic_support_channel + columns: + - iidb_reported + - afcs_reported + - bsp_reported + linkage: person_source_id -> FRS-channel person_id + reason: follows an injury, service or a death, not income + - kind: derive + scope: disability categories and flags re-derived on SPI-channel rows from the final reports with the frs_disability rule at its declared year; the categories, which read only AA, DLA and PIP, asserted unchanged + - kind: derive + output: receives_benefits_in_own_right + formula: universal_credit_reported + jsa_contrib_reported + jsa_income_reported + esa_contrib_reported + esa_income_reported > 0 (frs_education), SPI-channel rows; FRS rows asserted unchanged + - kind: aggregate_person_to_benunit + method: any_positive + consumed_only: true + aggregates: + universal_credit_reported_anchor: universal_credit_reported + - kind: aggregate_person_to_benunit + method: any_adult_under_state_pension_age + consumed_only: true + aggregates: + uc_age_eligible: age + - kind: assign_binary_with_anchored_residual + output: would_claim_uc + draw: would_claim_uc + rate_key: universal_credit + anchor: universal_credit_reported_anchor + population: uc_age_eligible + seed: 0 + rows: spi_synthetic_support_channel + outputs: [] + rewrites: + - jsa_contrib_reported + - jsa_income_reported + - esa_income_reported + - income_support_reported + - working_tax_credit_reported + - child_tax_credit_reported + - sda_reported + - ssmg_reported + - iidb_reported + - afcs_reported + - bsp_reported + - is_disabled_for_benefits + - is_enhanced_disabled_for_benefits + - is_severely_disabled_for_benefits + - receives_benefits_in_own_right + - would_claim_uc + notes: 'Runs on SPI-channel rows after uc_reporter_redraw, the last writer of Universal Credit reports, and before uc_capital_coherence and the Pension Credit and Child Benefit take-up stages (microcosm#1095, uk-data#514). The stage-2 forests of hmrc_spi_income_spine re-impute each SPI adult''s benefit reports from age, gender, region and the new incomes, with nothing of the benefit unit''s entitlement or claim history. This stage zeroes the SPI rows'' contributory and income-based JSA, income-related ESA, Income Support, Working and Child Tax Credit, Severe Disablement Allowance and Sure Start Maternity Grant reports, whose award needs an existing legacy claim, an out-of-work test, or a claim the copied household''s new incomes cannot carry (policyengine-uk pays income-related ESA as reported behind a capital test alone); restores Industrial Injuries Disablement Benefit, the Armed Forces Compensation Scheme and bereavement support from the FRS twin (person_source_id), since they follow an injury, service or a death; re-derives the disability flags (the categories, which read only AA, DLA and PIP, are asserted unchanged) and receives_benefits_in_own_right from the final reports; and redraws would_claim_uc for SPI benefit units as frs_take_up draws it for FRS units: a unit with a Universal Credit reporter claims, and the other units in the Universal Credit age population claim as the residual of the contract''s universal_credit rate on draws keyed on the SPI unit''s own identity. Contributory ESA, PIP, DLA, AA, Carer''s Allowance, State Pension and Winter Fuel Payment keep their draws, and FRS rows are never modified; contributory ESA is open to new claims and not income-tested, and the incapacity it needs follows the person, whose health and disability reports the SPI copy keeps.' - stage: uc_capital_coherence survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 benefit-unit TOTCAPB4 observations carried through the SPI support channel. @@ -3640,8 +3708,22 @@ stages: universal_credit_reported_anchor: universal_credit_reported - kind: redraw_spi_reporter_capital output: frs_benunit_capital - rows: spi_channel_post_fill_reporters - donor_rows: base_frs_reporters_with_available_capital + rows: spi_channel + donor_rows: base_frs_with_available_capital + reporter_status: universal_credit_reported_anchor + investment_income: savings_interest_income + dividend_income + other_investment_income, summed over benefit-unit members + investment_income_band_edges: + - 0.0 + - 240.0 + - 640.0 + - 2000.0 + - 8000.0 + minimum_cell_donors: 20 + coarsening: + - merge dependent-children bands + - drop couple status + - merge adjacent investment-income bands + - reporter status only dependent_children_bands: - '0' - '1' @@ -3662,7 +3744,7 @@ stages: rewrites: - frs_benunit_capital - would_claim_uc - notes: Runs after the last universal_credit_reported writer and before CGT cloning. Redraws only SPI post-fill reporters from weighted base-FRS reporter capital within dependent-children band by is_uc_couple cells (two retained FRS claimant/partner roles, independently of legal is_married), then applies the monotone reported-UC OR refresh. + notes: Runs after the last universal_credit_reported writer and before CGT cloning. Redraws every SPI benefit unit's capital, since the channel's incomes are SPI draws and the copied FRS answer no longer belongs to the unit (uk-data#495, microcosm#1095), from weighted base-FRS units with available capital in cells of UC reporter status by financial investment income band (interest, dividends and other investment income; property income is excluded because TOTCAPB4 counts accounts and assets) by is_uc_couple (two retained FRS claimant/partner roles, independently of legal is_married) by dependent-children band. A cell with fewer than 20 donors widens in the declared coarsening order, and reporter status is never coarsened. It then applies the monotone reported-UC OR refresh. - stage: pension_credit_take_up survey: Family Resources Survey 2024-25 source: 'DWP Income-related benefits: estimates of take-up, financial year ending 2024 (Pension Credit caseload take-up by component), applied to PolicyEngine-UK pre-take-up Pension Credit entitlement after the SPI income chain.' diff --git a/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json b/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json index d7f534547..9c4f01877 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json +++ b/packages/microcosm-build/src/microcosm/build/uk/target_fit_reviewed_exclusions.json @@ -1,13 +1,5 @@ { "schema_version": 2, "description": "Reviewed target-fit exclusions for the UK terminal battery (schema 2 per #610). Each entry defers one calibration target whose |relative error| breaches the 25% release bound, with the defect diagnosed, tracked, and owned elsewhere; the receipt records the reasoning, approver, adjudication reference, approval date, and expiry. The gate keeps the target BOUND in calibration (exclusion applies to the release fence only, never the solve), reports dormant entries, FAILS stale ones (targets back inside the bound), and FAILS expired ones until the adjudication is renewed, so this register cannot rot.", - "exclusions": { - "hmrc.spi_region.income_tax_by_region_12570_15000@E12000008@2025": { - "reason": "The frame carries too few taxpayers just above the personal allowance: 0.278m South East taxpayers with total income in GBP 12,570-15,000 at design weights against HMRC's projected 0.364m (nationally 2.31m against 2.97m; the North West and London are 28-31% short, the East 6%), and the ones it carries pay GBP 250 of income tax each against HMRC's GBP 215 (they sit higher in the band). The bound taxpayer-count rows make the solver scale these households up by a third to hit the count exactly, and the income-tax cell, carried by the same households, lands at +30.3% (its total-income sibling at +11.2%); main pulls the same cell from -20% to +22.6% by the same route. With the Table 3.6 amount rows projected by HMRC's band growth (microcosm#1063, 2026-10-02) the national employment rows fit within 4-12% and the cell still breaches, so the pull is the count gap, not the employment rows. The row was deferred on 2026-09-18 and retired on microcosm#1012 at +24.5%; deferred four weeks again while the lowest taxpayer band's support is corrected in the frame (the SPI support channel's coverage of the band and the FRS's small incomes around the frozen allowance), which is where the gap lives.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (the stack arms of 2026-10-02 on the review of #1089)", - "approved_on": "2026-10-02", - "expires_on": "2026-11-02" - } - } + "exclusions": {} } diff --git a/packages/microcosm-build/src/microcosm/build/uk/uk_population_targets.json b/packages/microcosm-build/src/microcosm/build/uk/uk_population_targets.json index 2cefb5368..34c63bc39 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/uk_population_targets.json +++ b/packages/microcosm-build/src/microcosm/build/uk/uk_population_targets.json @@ -2044,7 +2044,17 @@ "measurement": { "entity": "person", "concept": "uk.benefits.attendance_allowance.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2052,7 +2062,20 @@ "value_variable": "attendance_allowance", "from_entity": "person", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "country", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "ENGLAND", + "WALES" + ], + "map_to": "person" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to England and Wales (microcosm#1095, uk-data#490): DWP reports this benefit for England and Wales only since executive competence moved to the Scottish Government (Attendance Allowance from 1 April 2020; DWP benefit expenditure and caseload tables, Spring 2026, Notes), and OBR table 4.9 carries DWP's line. FRS code 12 also holds Scotland's Pension Age Disability Payment, which the Scottish Government funds, so the model column sums English and Welsh households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/attendance_allowance", @@ -2079,7 +2102,17 @@ "measurement": { "entity": "person", "concept": "uk.benefits.carers_allowance.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2087,7 +2120,20 @@ "value_variable": "carers_allowance", "from_entity": "person", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "country", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "ENGLAND", + "WALES" + ], + "map_to": "person" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to England and Wales (microcosm#1095, uk-data#490): DWP reports this benefit for England and Wales only since executive competence moved to the Scottish Government (Carer's Allowance from 3 September 2018; DWP benefit expenditure and caseload tables, Spring 2026, Notes), and OBR table 4.9 carries DWP's line. FRS code 13 also holds Scotland's Carer Support Payment, which the Scottish Government funds, so the model column sums English and Welsh households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/carers_allowance", @@ -2340,14 +2386,47 @@ ], "measurement": { "entity": "household", - "concept": "uk.benefits.esa.amount" + "concept": "uk.benefits.esa.amount", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { "metric_name": "obr/esa", "value_expression": "esa_income + esa_contrib", "map_to": "household", - "notes": "EFO incapacity-benefits line; uk-data sums benunit-level esa_income and person-level esa_contrib to household (compute/income.py:98-102). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "household" + } + ], + "notes": "EFO incapacity-benefits line; uk-data sums benunit-level esa_income and person-level esa_contrib to household (compute/income.py:98-102). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/esa", @@ -2374,7 +2453,18 @@ "measurement": { "entity": "benunit", "concept": "uk.benefits.housing_benefit.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2382,7 +2472,29 @@ "value_variable": "housing_benefit", "from_entity": "benunit", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/housing_benefit", @@ -2409,7 +2521,18 @@ "measurement": { "entity": "benunit", "concept": "uk.benefits.jsa.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2417,7 +2540,29 @@ "value_variable": "jsa", "from_entity": "benunit", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/jobseekers_allowance", @@ -2444,7 +2589,18 @@ "measurement": { "entity": "benunit", "concept": "uk.benefits.pension_credit.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2452,7 +2608,29 @@ "value_variable": "pension_credit", "from_entity": "benunit", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/pension_credit", @@ -2479,15 +2657,38 @@ "measurement": { "entity": "person", "concept": "uk.benefits.disability_benefits.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "wales" + ] + } + ] }, "bindings": { "policyengine": { "metric_name": "obr/pip", - "value_variable": "pip", + "value_expression": "pip + dla", "from_entity": "person", "map_to": "household", - "notes": "EFO line covers DLA and PIP combined; uk-data binds pip only - carried as-is for parity; adjudicate in microcosm#622. Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "country", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "ENGLAND", + "WALES" + ], + "map_to": "person" + } + ], + "notes": "The EFO line is \"Disability living allowance and personal independence payments\", so the row binds the engine's pip + dla (María's ruling of 2026-10-02, microcosm#1095); uk-data binds pip alone and microcosm#622 closed without adjudicating it. Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to England and Wales (microcosm#1095, uk-data#490): DWP reports this benefit for England and Wales only since executive competence moved to the Scottish Government (Disability Living Allowance and Personal Independence Payment from 1 April 2020; DWP benefit expenditure and caseload tables, Spring 2026, Notes), and OBR table 4.9 carries DWP's line. Scotland's Adult and Child Disability Payments are Scottish Government spending, so the model column sums English and Welsh households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/pip", @@ -2514,7 +2715,18 @@ "measurement": { "entity": "person", "concept": "uk.benefits.statutory_maternity_pay.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -2522,7 +2734,29 @@ "value_variable": "statutory_maternity_pay", "from_entity": "person", "map_to": "household", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "person" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/statutory_maternity_pay", @@ -2587,6 +2821,15 @@ "concept": "uk.benefits.benefit_cap.reduction", "operator": ">", "value": 0 + }, + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] } ] }, @@ -2603,7 +2846,29 @@ "value": 0 } ], - "notes": "Split of UC spend by benefit-cap status (compute/benefits.py:119-127). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Split of UC spend by benefit-cap status (compute/benefits.py:119-127). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/universal_credit_in_cap", @@ -2636,6 +2901,15 @@ "concept": "uk.benefits.benefit_cap.reduction", "operator": "==", "value": 0 + }, + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] } ] }, @@ -2652,7 +2926,29 @@ "value": 0 } ], - "notes": "Split of UC spend by benefit-cap status (compute/benefits.py:119-127). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Split of UC spend by benefit-cap status (compute/benefits.py:119-127). Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/universal_credit_outside_cap", @@ -2678,13 +2974,36 @@ ], "measurement": { "entity": "household", - "concept": "uk.benefits.winter_fuel_payment.amount" + "concept": "uk.benefits.winter_fuel_payment.amount", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "wales" + ] + } + ] }, "bindings": { "policyengine": { "metric_name": "obr/winter_fuel_allowance", "value_variable": "winter_fuel_allowance", - "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane)." + "household_conditions": [ + { + "variable": "country", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "ENGLAND", + "WALES" + ], + "map_to": "household" + } + ], + "notes": "Bound at the calendar-2025 window of the OBR fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window), María's rule of 2026-09-22 that fiscal-year facts take only the months to the end of the calibration calendar year (PolicyEngine/chronicle#280 lane). Scoped to England and Wales (microcosm#1095, uk-data#490): DWP reports this benefit for England and Wales only since executive competence moved to the Scottish Government (Winter Fuel Payment from 1 April 2024; DWP benefit expenditure and caseload tables, Spring 2026, Notes), and OBR table 4.9 carries DWP's line. Scotland's Pension Age Winter Heating Payment is Scottish Government spending, so the model column sums English and Welsh households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/winter_fuel_allowance", @@ -3679,6 +3998,15 @@ "concept": "uk.benefits.benefit_cap.reduction", "operator": ">", "value": 0 + }, + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] } ] }, @@ -3693,10 +4021,30 @@ "reduce": "any", "operator": ">", "value": 0 + }, + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "household" } ], "value_variable": "household_count", - "notes": "0/1 household indicator, not a benunit headcount (compute/benefits.py:14-21). The publisher's GBP 320.9m total-reduction companion is a computed annualization - excluded per the facts-only ADR." + "notes": "0/1 household indicator, not a benunit headcount (compute/benefits.py:14-21). The publisher's GBP 320.9m total-reduction companion is a computed annualization - excluded per the facts-only ADR. Scoped to Great Britain (microcosm#1095, uk-data#490): the DWP benefit cap statistics cover Great Britain (K03000001), so the model counts Great Britain households only." }, "axiom": { "metric_name": "dwp/benefit_capped_households", @@ -3815,6 +4163,17 @@ "entity": "benunit", "map_to": "household", "concept": "uk.benefit_unit.count", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ], "source_months": [ "2025-02", "2025-05", @@ -3835,7 +4194,29 @@ "value_variable": "benunit_count", "from_entity": "benunit", "map_to": "household", - "notes": "Paid ESA caseload, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025 (February, May, August, November 2025) of the three paid payment types, contributions based plus both plus income based; the published total also counts 'No payments - Credits only' claimants (78k to 84k through 2025), whose National Insurance record is credited without payment and whom no household frame can pay, so they are left out rather than described as unpublished (PolicyEngine/chronicle#280 section 5, chronicle#282). Calendar-2025 window per María's ruling of 2026-09-22; the year is the ESA income-related managed migration to Universal Credit (income based 499k in February to 30k in November), so a single point would misstate the year the calibration represents. Bound at benefit-unit grain on esa > 0 for incumbent parity; the cube counts claimants. The frame still carries fewer ESA reporters than the FRS (the SPI support channel, microcosm#869)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Paid ESA caseload, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025 (February, May, August, November 2025) of the three paid payment types, contributions based plus both plus income based; the published total also counts 'No payments - Credits only' claimants (78k to 84k through 2025), whose National Insurance record is credited without payment and whom no household frame can pay, so they are left out rather than described as unpublished (PolicyEngine/chronicle#280 section 5, chronicle#282). Calendar-2025 window per María's ruling of 2026-09-22; the year is the ESA income-related managed migration to Universal Credit (income based 499k in February to 30k in November), so a single point would misstate the year the calibration represents. Bound at benefit-unit grain on esa > 0 for incumbent parity; the cube counts claimants. The frame still carries fewer ESA reporters than the FRS (the SPI support channel, microcosm#869). Scoped to Great Britain (microcosm#1095, uk-data#490): the DWP fact covers Great Britain (K03000001), so the model column sums Great Britain households only." }, "axiom": { "metric_name": "dwp/esa_claimants", @@ -3904,6 +4285,17 @@ "entity": "person", "map_to": "household", "concept": "uk.person.count", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ], "source_months": [ "2025-02", "2025-05", @@ -3924,7 +4316,29 @@ "value_variable": "person_count", "from_entity": "person", "map_to": "household", - "notes": "Contributory ESA claimants, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025: payment types 'Contributions based' plus 'Both income and contributions based', so the row matches the model's esa_contrib > 0, which includes dual claimants (PolicyEngine/chronicle#280 section 5, chronicle#282; supersedes the August 2025 single-type count from the benefit statistics summary). The contributory caseload rises through 2025 as dual claimants lose the income-related part on migration to Universal Credit." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "person" + } + ], + "notes": "Contributory ESA claimants, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025: payment types 'Contributions based' plus 'Both income and contributions based', so the row matches the model's esa_contrib > 0, which includes dual claimants (PolicyEngine/chronicle#280 section 5, chronicle#282; supersedes the August 2025 single-type count from the benefit statistics summary). The contributory caseload rises through 2025 as dual claimants lose the income-related part on migration to Universal Credit. Scoped to Great Britain (microcosm#1095, uk-data#490): the DWP fact covers Great Britain (K03000001), so the model column sums Great Britain households only." }, "axiom": { "metric_name": "dwp/esa_contrib_claimants", @@ -3986,6 +4400,17 @@ "entity": "benunit", "map_to": "household", "concept": "uk.benefit_unit.count", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ], "source_months": [ "2025-02", "2025-05", @@ -4006,7 +4431,29 @@ "value_variable": "benunit_count", "from_entity": "benunit", "map_to": "household", - "notes": "Income-related ESA claimants, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025: payment types 'Income based' plus 'Both income and contributions based', so the row matches the model's esa_income > 0, which includes dual claimants (PolicyEngine/chronicle#280 section 5, chronicle#282; supersedes the August 2025 single-type count). The calendar-2025 mean spans the managed migration to Universal Credit (759k in February to 50k in November); the FRS 2024-25 base carries the pre-migration caseload, so this row measures the year's average, not the year-end." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Income-related ESA claimants, Great Britain, as the mean of the four quarterly Stat-Xplore points inside calendar 2025: payment types 'Income based' plus 'Both income and contributions based', so the row matches the model's esa_income > 0, which includes dual claimants (PolicyEngine/chronicle#280 section 5, chronicle#282; supersedes the August 2025 single-type count). The calendar-2025 mean spans the managed migration to Universal Credit (759k in February to 50k in November); the FRS 2024-25 base carries the pre-migration caseload, so this row measures the year's average, not the year-end. Scoped to Great Britain (microcosm#1095, uk-data#490): the DWP fact covers Great Britain (K03000001), so the model column sums Great Britain households only." }, "axiom": { "metric_name": "dwp/esa_income_claimants", @@ -4067,7 +4514,18 @@ "measurement": { "entity": "person", "map_to": "household", - "concept": "uk.person.count" + "concept": "uk.person.count", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -4082,7 +4540,29 @@ "value_variable": "person_count", "from_entity": "person", "map_to": "household", - "notes": "uk-data binds the JSA claimant count to contributory JSA only (jsa_contrib) - carried as-is for parity; adjudicate in microcosm#622. DWP's count (71,000 at August 2025) is New Style, contributory JSA only, after a methodology change from August 2025 that removed inactive claims; not comparable with earlier vintages. FRS 2024-25 reports 63k JSA benefit units at design weights, so the frame's excess is not the source: spine-q carries 181k contributory reporters, 161k of them in the SPI support channel's synthetic households (#882, microcosm#869)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "person" + } + ], + "notes": "uk-data binds the JSA claimant count to contributory JSA only (jsa_contrib) - carried as-is for parity; adjudicate in microcosm#622. DWP's count (71,000 at August 2025) is New Style, contributory JSA only, after a methodology change from August 2025 that removed inactive claims; not comparable with earlier vintages. FRS 2024-25 reports 63k JSA benefit units at design weights, so the frame's excess is not the source: spine-q carries 181k contributory reporters, 161k of them in the SPI support channel's synthetic households (#882, microcosm#869). Scoped to Great Britain (microcosm#1095, uk-data#490): the DWP fact covers Great Britain (K03000001), so the model column sums Great Britain households only." }, "axiom": { "metric_name": "dwp/jsa_claimants", @@ -15711,7 +16191,18 @@ "measurement": { "entity": "benunit", "concept": "uk.benefits.universal_credit.amount", - "map_to": "household" + "map_to": "household", + "filters": [ + { + "concept": "uk.geography.country", + "operator": "in", + "value": [ + "england", + "scotland", + "wales" + ] + } + ] }, "bindings": { "policyengine": { @@ -15719,7 +16210,29 @@ "value_variable": "universal_credit", "from_entity": "benunit", "map_to": "household", - "notes": "Total UC expenditure: the sum of the OBR EFO welfare-cap cells (universal_credit_in_cap + universal_credit_outside_cap), bound at the calendar-2025 window of the two cells' fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window over the two-concept selector, one series per concept) so the total and its two components share one basis (Vahid's review of microcosm#1006, item 3) against the model's annual award after the benefit cap and deductions at policy year 2025, UK incl. Northern Ireland. The split rows stay excluded: the model cannot attribute spend to the welfare-cap concept (microcosm#757). Cash advances and third-party payments are not modelled (#882)." + "household_conditions": [ + { + "variable": "region", + "entity": "household", + "reduce": "any", + "operator": "in", + "value": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND" + ], + "map_to": "benunit" + } + ], + "notes": "Total UC expenditure: the sum of the OBR EFO welfare-cap cells (universal_credit_in_cap + universal_credit_outside_cap), bound at the calendar-2025 window of the two cells' fiscal years (three twelfths of FY2024-25, nine twelfths of FY2025-26; calendar_year_window over the two-concept selector, one series per concept) so the total and its two components share one basis (Vahid's review of microcosm#1006, item 3) against the model's annual award after the benefit cap and deductions at policy year 2025, UK incl. Northern Ireland. The split rows stay excluded: the model cannot attribute spend to the welfare-cap concept (microcosm#757). Cash advances and third-party payments are not modelled (#882). Scoped to Great Britain (microcosm#1095, uk-data#490): OBR table 4.9 reports this line inside 'DWP social security', whose figures cover Great Britain and residents overseas (DWP benefit expenditure and caseload tables, Spring 2026, Notes 3), and lists Northern Ireland social security on rows of its own, so the model column sums Great Britain households only. The Chronicle fact still carries the UK code K02000001." }, "axiom": { "metric_name": "obr/universal_credit", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py index 653fe1bef..af15e80d2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/battery_bindings.py @@ -1687,6 +1687,9 @@ def _ledger_compile_parity_required_artifacts( # microcosm#1069 c7 pension_credit_take_up stage-health check. "maximum_take_up_deviation", "minimum_entitled_units", + # microcosm#1095 spi_benefit_coherence stage-health check. + "zeroed_columns", + "restored_columns", # microcosm#1063 child_benefit_take_up stage-health check. "maximum_claim_rate_deviation", "maximum_age_claim_rate_deviation", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/calibration_run.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/calibration_run.py index 23e85b0ae..37044ffaf 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/calibration_run.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/calibration_run.py @@ -103,6 +103,7 @@ "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", + "uk_stage_spi_benefit_coherence", "uk_stage_pension_credit_take_up", "uk_stage_child_benefit_take_up", "uk_stage_cgt_incidence_clone_mass", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_services.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_services.py index b878ab233..e76473d55 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_services.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_services.py @@ -22,6 +22,7 @@ donor_uprating_factors, uprating_operation, ) +from microcosm.build.uk_runtime.etb_vat import UK_ETB_FAMILY_ROLE_COUNTS from microcosm.build.uk_runtime.frs_spine import read_pinned_tab from microcosm.build.uk_runtime.national_frame import ( uk_household_mass_conservation_receipt, @@ -35,6 +36,7 @@ UKSupportClipResult, support_clip_to_donor_with_receipt, ) +from microcosm.build.uk_runtime.uc_relationships import household_family_role_counts from microcosm.frame import Frame from microcosm.frame.rules import assert_rules_engine_country @@ -51,10 +53,10 @@ "hbai_household_net_income", ) # The education counts are not engine variables: the incumbent derives them -# from person current_education (etb.py:180-186). Only these materialize. +# from person current_education (etb.py:180-186), and the adult and child +# counts are the household's FRS family roles (``UK_ETB_FAMILY_ROLE_COUNTS``). +# Only these materialize. UK_ETB_SERVICES_ENGINE_VARIABLES = ( - "is_adult", - "is_child", "is_SP_age", "dla", "pip", @@ -402,7 +404,11 @@ def person_sum(values: np.ndarray) -> np.ndarray: result = pd.DataFrame(index=household.index) education = np.asarray(materialized["current_education"]).astype(str) + adults, children = household_family_role_counts(person, household) for predictor in UK_ETB_SERVICES_PREDICTORS: + if predictor in UK_ETB_FAMILY_ROLE_COUNTS: + result[predictor] = adults if predictor == "is_adult" else children + continue if predictor in UK_ETB_SERVICES_EDUCATION_COUNTS: labels = UK_ETB_SERVICES_EDUCATION_COUNTS[predictor] result[predictor] = person_sum(np.isin(education, labels)) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_vat.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_vat.py index 10055e7c4..f3b8fa42d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_vat.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/etb_vat.py @@ -25,6 +25,7 @@ UKSupportClipResult, support_clip_to_donor_with_receipt, ) +from microcosm.build.uk_runtime.uc_relationships import household_family_role_counts from microcosm.frame import Frame from microcosm.frame.rules import assert_rules_engine_country @@ -37,6 +38,16 @@ "is_SP_age", "household_net_income", ) +#: The ETB donor's ``adults`` and ``childs`` count a household's adults and +#: dependent children, so the recipient counts are its FRS claimants and +#: partners and its other members (``is_uc_claimant``), not the engine's +#: age-18 split (uk-data#486, microcosm#1095). Only the rest materialize. +UK_ETB_FAMILY_ROLE_COUNTS = ("is_adult", "is_child") +UK_ETB_VAT_ENGINE_PREDICTORS = tuple( + predictor + for predictor in UK_ETB_VAT_PREDICTORS + if predictor not in UK_ETB_FAMILY_ROLE_COUNTS +) UK_ETB_VAT_OUTPUT_COLUMNS = ("full_rate_vat_expenditure_rate",) # The donor-realized support includes negative rates (totvat can exceed expdis # in the raw ETB accounts), so the output stays out of the nonnegative gate and @@ -228,19 +239,24 @@ def etb_vat_configuration( def recipient_predictors(frame: Frame, engine: object) -> pd.DataFrame: """Materialize ETB VAT recipient predictors at household grain. - Predictors materialize at their native entity (is_adult / is_child / - is_SP_age are person booleans) and aggregate to household by - person_household_id — direct engine arrays would crash the licensed - build on the person/household length mismatch (the E5 review class). + Engine predictors materialize at their native entity (is_SP_age is a + person boolean) and aggregate to household by person_household_id — direct + engine arrays would crash the licensed build on the person/household + length mismatch (the E5 review class). The adult and child counts are the + household's FRS family roles. """ materialized = engine.materialize( - frame, UK_ETB_VAT_PREDICTORS, uk_time_period(frame) + frame, UK_ETB_VAT_ENGINE_PREDICTORS, uk_time_period(frame) ) household = frame.table("household") person = frame.table("person") result = pd.DataFrame(index=household.index) + adults, children = household_family_role_counts(person, household) for predictor in UK_ETB_VAT_PREDICTORS: + if predictor in UK_ETB_FAMILY_ROLE_COUNTS: + result[predictor] = adults if predictor == "is_adult" else children + continue declared = str(engine.variable_metadata(predictor).entity) values = np.asarray(materialized[predictor]) if declared == "household": diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_council_tax.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_council_tax.py index 534f597ef..aa74ae1bf 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_council_tax.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_council_tax.py @@ -11,10 +11,10 @@ from microcosm.build.source_manifest import SourceStageSpec from microcosm.build.uk_runtime.frs_spine import ( + SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE, WEEKS_IN_YEAR, normalize_ids, read_pinned_tab, - scottish_water_and_sewerage_weekly, ) from microcosm.build.uk_runtime.national_frame import ( uk_household_weight_kind, @@ -26,6 +26,82 @@ FRS_COUNCIL_TAX_OUTPUT_COLUMNS = ("council_tax",) SCOTLAND_GVTREGNO = 12 +#: Raw household cells the derivation reads; the pinned tab carries them all. +FRS_COUNCIL_TAX_RAW_COLUMNS = ( + "ctannual", + "ctreb", + "ctrebamt", + "gvtregno", + "ctband", + "adulth", + "cwatamt1", + "csewamt1", + "cwatamtd", +) +#: Share of the gross Scottish water and sewerage charges that DWP's CTANNUAL +#: carries for a council tax reduction recipient. Netting 65% of the gross +#: charges brings Scottish recipients' bills to the non-recipient cells (ratio +#: 1.00 overall, 0.98-1.01 in bands A-F; uk-data#499), the Water Charges +#: Reduction Scheme's 35% maximum; non-recipients carry the gross charges in +#: full, status discount or not: netted that way, discounted bills sit at +#: 0.75 to 0.76 of undiscounted ones in the same band, the 25% discount. +SCOTTISH_CHARGES_IN_RECIPIENT_BILL = SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE +FRS_COUNCIL_TAX_STAGE_NAME = "frs_council_tax" +FRS_COUNCIL_TAX_IMPUTATION_KIND = "impute_cell_means" + + +def frs_council_tax_operation_parameters() -> dict[str, Any]: + """The ``impute_cell_means`` declaration ``derive_council_tax`` implements.""" + + return { + "kind": FRS_COUNCIL_TAX_IMPUTATION_KIND, + "cells": ["gvtregno", "ctband", "adulth == 1"], + "donor_filter": "raw ctreb != 1 and ctannual > 0", + "missing": "raw ctannual < 0 or NaN", + "value": ( + "council tax before council tax reduction: CTANNUAL net of the " + "Scottish water and sewerage charges ((CWATAMT1 + CSEWAMT1) x " + "365.25/7, at 0.65 where CTREB is 1; CWATAMTD where CWATAMT1 is not " + "positive), plus CTREBAMT x 365.25/7 where CTREB is 1 and CTREBAMT " + "> 0; a CTREB 1 household without a positive CTREBAMT takes the " + "larger of its netted CTANNUAL and its cell mean" + ), + } + + +def assert_frs_council_tax_stage_parameters(stage: SourceStageSpec) -> None: + """Closed-world drift assert: the manifest declares the implemented rule.""" + + if stage.stage != FRS_COUNCIL_TAX_STAGE_NAME: + raise ValueError(f"frs_council_tax transform received stage {stage.stage!r}.") + operations = list(stage.operations) + kinds = [operation.kind for operation in operations] + if kinds != ["read_tables", FRS_COUNCIL_TAX_IMPUTATION_KIND]: + raise ValueError( + "frs_council_tax stage must declare read_tables followed by " + f"{FRS_COUNCIL_TAX_IMPUTATION_KIND}, got {kinds}." + ) + declared = {"kind": operations[1].kind, **dict(operations[1].parameters)} + expected = frs_council_tax_operation_parameters() + drifted = sorted( + key + for key in {*declared, *expected} + if _plain(declared.get(key)) != _plain(expected.get(key)) + ) + if drifted: + raise ValueError( + "frs_council_tax impute_cell_means declaration drifted from the " + f"rule the runtime implements on parameter(s) {drifted} " + "(uk-data#496/#499, microcosm#1095)." + ) + + +def _plain(value: object) -> object: + if isinstance(value, Mapping): + return {key: _plain(item) for key, item in value.items()} + if isinstance(value, (list, tuple)): + return [_plain(item) for item in value] + return value class UKFRSCouncilTaxStageTransform: @@ -46,6 +122,7 @@ def output_columns() -> tuple[str, ...]: def add_frs_council_tax( frame: Frame, raw_dir: str | Path, *, stage: SourceStageSpec ) -> Frame: + assert_frs_council_tax_stage_parameters(stage) artifacts = _artifact_by_table(stage) household_raw = normalize_ids( read_pinned_tab( @@ -72,34 +149,79 @@ def add_frs_council_tax( def derive_council_tax( household: pd.DataFrame, household_raw: pd.DataFrame ) -> pd.Series: - """Impute raw missing council tax from raw region/band/adult cells.""" - + """The council tax bill after discounts and before council tax reduction. + + FRS 2024-25 ``CTANNUAL`` is the "Annual CT amount after discounts/reduction" + (DV summary, UKDS SN 9563), derived with the reported reduction ``CTREB`` / + ``CTREBAMT``; the engine reads ``council_tax`` as the liability before + council tax reduction. A household reporting a reduction (``CTREB`` 1) + therefore gets its weekly ``CTREBAMT`` added back, a full reduction + (``CTANNUAL`` 0) included: on the raw tab that restores the recipients' + bills to the non-recipients' in the same region, band and single-adult + cell (ratio 0.99 in England, 1.01 in Wales; uk-data#496/#499, + microcosm#1095). A recipient with no positive amount has an unknown + reduction and takes the larger of its bill and its cell's mean. Missing + or negative bills take the cell mean. The cells pool non-recipients with + a positive bill only, since recipients' ``CTANNUAL`` is net of their + reduction. + + Scottish bills carry the water and sewerage charges, which council tax + reduction does not cover. They are netted at the gross cells + ``CWATAMT1`` + ``CSEWAMT1``, in full for non-recipients and at + ``SCOTTISH_CHARGES_IN_RECIPIENT_BILL`` for recipients, the shares DWP's + derivation embeds (uk-data#499); a household with no gross water cell + nets its recorded ``CWATAMTD``. The charge a household pays is a separate + quantity, ``frs_spine.scottish_water_and_sewerage_weekly``. + """ + + missing_columns = sorted(set(FRS_COUNCIL_TAX_RAW_COLUMNS) - set(household_raw)) + if missing_columns: + raise KeyError(f"FRS council tax needs raw household cells {missing_columns}.") raw = household_raw.set_index("household_id") aligned = raw.reindex(household["household_id"]) - ctannual = pd.to_numeric(aligned["ctannual"], errors="coerce") - gvtregno = pd.to_numeric(aligned["gvtregno"], errors="coerce") - ctband = pd.to_numeric(aligned["ctband"], errors="coerce") - single_adult = pd.to_numeric(aligned["adulth"], errors="coerce") == 1 - # Netted with the same helper the spine's water_and_sewerage_charges uses, - # so the amount removed from the council tax bill is exactly the amount - # charged as water and sewerage. See its docstring for the FRS 2024-25 - # cell retirement (CWATAMT/CSEWAMT are empty in this vintage). - scottish_water = np.where( - gvtregno == SCOTLAND_GVTREGNO, - scottish_water_and_sewerage_weekly(aligned) * WEEKS_IN_YEAR, - 0.0, + + def number(column: str) -> pd.Series: + return pd.to_numeric(aligned[column], errors="coerce") + + def positive(column: str) -> pd.Series: + return number(column).fillna(0.0).clip(lower=0.0) + + ctannual = number("ctannual") + gvtregno = number("gvtregno") + ctband = number("ctband") + single_adult = number("adulth") == 1 + recipient = number("ctreb") == 1 + reduction = positive("ctrebamt") * WEEKS_IN_YEAR + known_reduction = recipient & (reduction > 0) + + gross_charges = positive("cwatamt1") + positive("csewamt1") + netted_weekly = np.where( + positive("cwatamt1") > 0, + gross_charges * np.where(recipient, SCOTTISH_CHARGES_IN_RECIPIENT_BILL, 1.0), + positive("cwatamtd"), ) - tax_only = pd.Series(np.maximum(ctannual - scottish_water, 0), index=aligned.index) - donors = ctannual > 0 + netted = np.where(gvtregno == SCOTLAND_GVTREGNO, netted_weekly * WEEKS_IN_YEAR, 0.0) + tax_only = pd.Series(np.maximum(ctannual - netted, 0), index=aligned.index) + + donors = ~recipient & (ctannual > 0) cell_mean = tax_only[donors].groupby( [gvtregno[donors], ctband[donors], single_adult[donors]], dropna=False ).mean() keys = pd.MultiIndex.from_arrays([gvtregno, ctband, single_adult]) imputed = pd.Series(keys.map(cell_mean).to_numpy(dtype=float), index=aligned.index) imputed = imputed.fillna(0.0).clip(lower=0) + missing = (ctannual < 0) | ctannual.isna() - result = pd.Series(np.where(missing, imputed, tax_only), index=aligned.index) - return result.fillna(0.0).clip(lower=0) + gross = np.where( + missing, + imputed, + np.where( + known_reduction, + np.maximum(ctannual - netted + reduction, 0), + np.where(recipient, np.maximum(tax_only, imputed), tax_only), + ), + ) + return pd.Series(gross, index=aligned.index).fillna(0.0).clip(lower=0) def _artifact_by_table(stage: SourceStageSpec) -> dict[str, Mapping[str, Any]]: diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_spine.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_spine.py index 7d0ab38ba..e60ebbd19 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_spine.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_spine.py @@ -128,27 +128,33 @@ 6: "DIVORCED", } +# FRS BENEFITS codes summed into each reported amount. Scotland's Adult +# Disability Payment (117 daily living, 118 mobility) mirrors PIP's components +# and rates, and Child Disability Payment (121 care, 122 mobility) mirrors DLA's, +# so each lands in the column of the benefit it replaces (FRS 2024-25 variable +# listing, UKDS SN 9563; uk-data#500, microcosm#1095). Codes 69 and 70 are +# benefit recoveries, not income, and stay unmapped. BENEFIT_CODES = { - "child_benefit": 3, - "income_support": 19, - "housing_benefit": 94, - "attendance_allowance": 12, - "dla_sc": 1, - "dla_m": 2, - "iidb": 15, - "carers_allowance": 13, - "sda": 10, - "afcs": 8, - "ssmg": 22, - "pension_credit": 4, - "child_tax_credit": 91, - "working_tax_credit": 90, - "state_pension": 5, - "winter_fuel_allowance": 62, - "incapacity_benefit": 17, - "universal_credit": 95, - "pip_m": 97, - "pip_dl": 96, + "child_benefit": (3,), + "income_support": (19,), + "housing_benefit": (94,), + "attendance_allowance": (12,), + "dla_sc": (1, 121), + "dla_m": (2, 122), + "iidb": (15,), + "carers_allowance": (13,), + "sda": (10,), + "afcs": (8,), + "ssmg": (22,), + "pension_credit": (4,), + "child_tax_credit": (91,), + "working_tax_credit": (90,), + "state_pension": (5,), + "winter_fuel_allowance": (62,), + "incapacity_benefit": (17,), + "universal_credit": (95,), + "pip_m": (97, 118), + "pip_dl": (96, 117), } # FRS adult HOURTOT: total hours of care provided per week, a banded derived @@ -649,9 +655,9 @@ def _add_benefits( var2 = _number(benefits, "var2") amount = _number(benefits, "benamt") person_id = benefits.get("person_id", pd.Series(dtype="float64")) - for name, code in BENEFIT_CODES.items(): + for name, codes in BENEFIT_CODES.items(): pe_person[f"{name}_reported"] = ( - _sum_to_entity(amount * (benefit == code), person_id, person["person_id"]) + _sum_to_entity(amount * benefit.isin(codes), person_id, person["person_id"]) * WEEKS_IN_YEAR ) pe_person["jsa_contrib_reported"] = ( @@ -946,14 +952,40 @@ def _positive(frame: pd.DataFrame, column: str) -> pd.Series: return np.maximum(_number(frame, column), 0) +#: The Water Charges Reduction Scheme's maximum reduction, 2021-27. A council +#: tax reduction recipient's charges fall by R = 35 x (A/B) - D percentage +#: points of the gross charge, unless R < 0, on top of the council tax status +#: discount D, where A is the reduction and B the council tax before it, after +#: discounts (Scottish Government, "Water services - charging principles: 2021 +#: to 2027", Annex A): the combined reduction is the larger of D and 35% x A/B. +SCOTTISH_WATER_CHARGES_REDUCTION_MAXIMUM = 0.35 +#: Share of the gross charges a full council tax reduction recipient without a +#: status discount pays, and the share DWP's CTANNUAL carries for every +#: recipient, which ``frs_council_tax`` nets (uk-data#499, microcosm#1095). +SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE = ( + 1.0 - SCOTTISH_WATER_CHARGES_REDUCTION_MAXIMUM +) +#: FRS 2024-25 CT25D50D codes to the status discount they record, for +#: households with CTDISC 1 (SN 9563 variable listing). +FRS_STATUS_DISCOUNT_BY_CODE = {1: 0.25, 2: 0.5} +SCOTTISH_WATER_AND_SEWERAGE_RAW_COLUMNS = ( + "cwatamt1", + "csewamt1", + "cwatamtd", + "ctdisc", + "ct25d50d", + "ctreb", +) + + def scottish_water_and_sewerage_weekly(household: pd.DataFrame) -> pd.Series: - """Weekly Scottish water + sewerage charge, net of the household's discount. + """Weekly Scottish water + sewerage charge the household pays. Scotland is not asked ``WATSEWRT`` — its water and sewerage charges ride on - the council tax bill — so the amount must be assembled from the council-tax + the council tax bill — so the amount is assembled from the council-tax water/sewerage cells. - FRS 2024-25 retired the two cells the incumbent used. ``CWATAMT``/ + FRS 2024-25 retired the two cells the incumbent used. ``CWATAMT``/ ``CSEWAMT`` ("Wat./Sew. Charge: Final value after discount") are still present as headers but carry no data at all in this vintage, and the FRS replaced them with the derived ``CWATAMT1``/``CSEWAMT1`` ("Weeklyised gross @@ -961,46 +993,71 @@ def scottish_water_and_sewerage_weekly(household: pd.DataFrame) -> pd.Series: 2024-25 as variable was removed from the dataset for 2024-25" — SN 9563 ``9563_dv_summary_2425.xlsx``). - The replacements are **gross**, where the retired cells were **after - discount**, and the FRS publishes no discounted sewerage counterpart. - ``CWATAMTD`` ("Deriv Council Tax water charge -Scot") does carry the - discount, so the household's own discount factor is observable as - ``CWATAMTD / CWATAMT1`` and applies to the sewerage side of the same bill. - That keeps the incumbent's semantics — what the household actually pays — - across the vintage change rather than silently switching to a gross basis. - - Every value is weeklyised (all five cells sit in the FRS "weekly variables" - listing), so callers apply ``WEEKS_IN_YEAR`` themselves. + The household pays the gross charges less the status discount its council + tax records, which applies to the water and sewerage charges too (25% or + 50%: ``CTDISC`` 1 with ``CT25D50D`` 1 or 2). For a council tax reduction + recipient (``CTREB`` 1) the Water Charges Reduction Scheme tops that + discount up to ``SCOTTISH_WATER_CHARGES_REDUCTION_MAXIMUM`` of the gross + charges, so a recipient pays the gross charges less the larger of its + discount and 35% (uk-data#499, microcosm#1095). ``CWATAMTD`` ("Deriv + Council Tax water charge -Scot") is not that amount: on the 2024-25 tab it + sits at a median 0.83 of the gross water charge for undiscounted + non-recipients and 0.87 for undiscounted recipients, so it is read only + where no gross water cell exists. + + The scheme's 35% tapers with the share A/B of the council tax the + reduction covers, but every recipient here takes the full-reduction case, + A/B = 1. 86% of Scotland's recipients receive full council tax reduction + (Council Tax Reduction in Scotland 2024-25, March 2025, average award + GBP 16.55 a week), while none of the 234 Scottish recipients with a + recorded ``CTREBAMT`` on the 2024-25 tab pays nothing after it (19% of + English recipients do) and their recorded amounts have a median of GBP 6 a + week, so the recorded amount cannot carry the share. + + Every value is weeklyised (all the amount cells sit in the FRS "weekly + variables" listing), so callers apply ``WEEKS_IN_YEAR`` themselves. On the 2024-25 tab the domain splits cleanly: 1,641 Scottish households - carry a positive gross water charge and a well-defined factor in - (1/3, 1]; 22 carry a recorded ``CWATAMTD`` with no gross bill cell, and - their ``CSEWAMT1`` is zero, so the fallback factor cannot move them; 21 - carry no council-tax cells at all and fall to zero. + carry a positive gross water charge; 22 carry a recorded ``CWATAMTD`` + with no gross bill cell, and their ``CSEWAMT1`` is zero, so they pay the + recorded water charge; 21 carry no council-tax cells at all and fall to + zero. """ - water = _positive(household, "cwatamtd") + missing = sorted(set(SCOTTISH_WATER_AND_SEWERAGE_RAW_COLUMNS) - set(household)) + if missing: + raise KeyError(f"Scottish water assembly needs raw household cells {missing}.") water_gross = _positive(household, "cwatamt1") sewerage_gross = _positive(household, "csewamt1") billed = water_gross > 0 - # The correctness of the discount fallback rests on the domain claim - # above: a household with no gross water bill carries no sewerage gross - # either, so the fallback factor of 1.0 can never re-introduce the gross - # basis this helper exists to avoid. That claim is a property of the - # vintage, not of the code — so it is asserted, and a vintage that breaks - # it refuses at build time instead of silently paying gross sewerage. - undiscountable = ~billed & (sewerage_gross > 0) - if bool(undiscountable.any()): + # A household with no gross water bill carries no gross sewerage either, + # so its recorded CWATAMTD is the whole charge. That claim is a property + # of the vintage, not of the code — so it is asserted, and a vintage that + # breaks it refuses at build time instead of mixing the two bases. + unbilled_sewerage = ~billed & (sewerage_gross > 0) + if bool(unbilled_sewerage.any()): raise ValueError( "Scottish water assembly: " - f"{int(undiscountable.sum())} household(s) carry a gross sewerage " - "charge (CSEWAMT1 > 0) with no gross water bill (CWATAMT1 == 0), " - "so no discount factor is observable for them. Adding sewerage at " - "gross would silently change the charge's after-discount meaning; " - "this vintage needs an adjudicated rule for these households." + f"{int(unbilled_sewerage.sum())} household(s) carry a gross sewerage " + "charge (CSEWAMT1 > 0) with no gross water bill (CWATAMT1 == 0), so " + "their charge cannot be assembled on one basis; this vintage needs " + "an adjudicated rule for these households." ) - discount = np.where(billed, water / water_gross.where(billed, 1.0), 1.0) - return water + sewerage_gross * discount + discount = ( + _number(household, "ct25d50d") + .map(FRS_STATUS_DISCOUNT_BY_CODE) + .where(_number(household, "ctdisc") == 1, 0.0) + .fillna(0.0) + ) + reduction = np.where( + _number(household, "ctreb") == 1, + np.maximum(discount, SCOTTISH_WATER_CHARGES_REDUCTION_MAXIMUM), + discount, + ) + paid = (water_gross + sewerage_gross) * (1.0 - reduction) + return pd.Series( + np.where(billed, paid, _positive(household, "cwatamtd")), index=household.index + ) def _reject_nan(frame: pd.DataFrame, entity: str) -> None: diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py index df857db58..abf61714b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -108,6 +108,11 @@ # open-surface SPI income stage, which would otherwise bind them. "spi_housing_shell", "uc_reporter_redraw", + # The SPI benefit pass rewrites cells the open-surface readers before + # it bind: the SPI income stage's reports, frs_disability's flags, + # frs_education's receives_benefits_in_own_right and frs_take_up's + # would_claim_uc (microcosm#1095). + "spi_benefit_coherence", "uc_capital_coherence", # The Pension Credit redraw rewrites ``frs_take_up``'s would_claim_pc, # which the open-surface readers before it bind (microcosm#1069). @@ -285,12 +290,57 @@ # One temporary engine materialization of Child Benefit eligibility and # adjusted net income over the whole frame: an open surface. "child_benefit_take_up": None, + "spi_benefit_coherence": frozenset( + { + ("person", "person_support_channel"), + ("person", "person_source_id"), + *( + ("person", column) + for column in ( + "jsa_contrib_reported", + "jsa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported", + "iidb_reported", + "afcs_reported", + "bsp_reported", + "universal_credit_reported", + "esa_contrib_reported", + "esa_income_reported", + "attendance_allowance_reported", + "dla_sc_reported", + "dla_m_reported", + "pip_m_reported", + "pip_dl_reported", + "incapacity_benefit_reported", + "aa_category", + "dla_sc_category", + "dla_m_category", + "pip_m_category", + "pip_dl_category", + "is_disabled_for_benefits", + "is_enhanced_disabled_for_benefits", + "is_severely_disabled_for_benefits", + "receives_benefits_in_own_right", + ) + ), + ("benunit", "benunit_support_channel"), + ("benunit", "would_claim_uc"), + } + ), "uc_capital_coherence": frozenset( { ("person", "is_benunit_head"), ("person", "is_parent"), ("person", "person_support_channel"), ("person", "universal_credit_reported"), + # The capital cells' financial investment income (microcosm#1095). + ("person", "savings_interest_income"), + ("person", "dividend_income"), + ("person", "other_investment_income"), ("benunit", "benunit_support_channel"), ("benunit", "dependent_children"), ("benunit", "frs_benunit_capital"), @@ -787,6 +837,35 @@ def _cells( *_cells("person", ("housing_benefit_reported", "council_tax_benefit_reported")), ), "uc_reporter_redraw": (_Cell("person", "universal_credit_reported", "float64"),), + "spi_benefit_coherence": ( + *_cells( + "person", + ( + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported", + "iidb_reported", + "afcs_reported", + "bsp_reported", + ), + ), + *_cells( + "person", + ( + "is_disabled_for_benefits", + "is_enhanced_disabled_for_benefits", + "is_severely_disabled_for_benefits", + "receives_benefits_in_own_right", + ), + "bool", + ), + _Cell("benunit", "would_claim_uc", "bool"), + ), "uc_capital_coherence": ( _Cell("benunit", "uc_reported_capital", "float64"), _Cell("benunit", "frs_benunit_capital", "float64"), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_kernels.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_kernels.py index ff99c0d30..ed2051e68 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_kernels.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph_kernels.py @@ -47,7 +47,11 @@ from .. import stage_evidence from . import ( bus_use_incidence, + frs_disability, + frs_education, frs_hmrc_source, + frs_take_up, + spi_support, uc_capital_coherence, uc_relationships, was_wealth, @@ -95,6 +99,7 @@ "hmrc_spi_income_spine": "spi_spine", "spi_housing_shell": "spi_housing_shell", "uc_reporter_redraw": "uc_reporter_redraw", + "spi_benefit_coherence": "spi_benefit_coherence", "uc_capital_coherence": "uc_capital_coherence", "pension_credit_take_up": "pension_credit_take_up", "child_benefit_take_up": "child_benefit_take_up", @@ -127,6 +132,17 @@ "etb_vat": (uk_engine_adapter,), "etb_services": (uk_engine_adapter,), "uc_reporter_redraw": (uc_relationships, uk_engine_adapter), + # The SPI benefit pass restores from the FRS twin through the support + # channel's lineage, re-derives the disability flags and the own-right + # rule, draws over the take-up population and maps household weights to + # benefit units as the UC capital stage does (microcosm#1095). + "spi_benefit_coherence": ( + spi_support, + frs_disability, + frs_education, + frs_take_up, + uc_capital_coherence, + ), "uc_capital_coherence": (uc_relationships,), # The Pension Credit redraw reuses the UC stage's household-to-benefit-unit # weight mapping and the adapter's engine materialization. @@ -404,7 +420,7 @@ def _fixture_descriptor( missing = sorted(set(_STAGE_MODULES) - set(stages)) extra = sorted(set(stages) - set(_STAGE_MODULES)) raise ValueError( - "UK parity fixture must describe the current 38-stage spine " + "UK parity fixture must describe the current 39-stage spine " f"(missing={missing}, extra={extra})." ) return descriptor, stages @@ -444,6 +460,7 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: from .regional_uprating import UKRegionalPropertyUpratingStageTransform from .salary_sacrifice import UKSalarySacrificeStageTransform from .spi_band_donors import UKSPIIncomeBandDonorStageTransform + from .spi_benefit_coherence import UKSPIBenefitCoherenceStageTransform from .spi_housing_shell import UKSPIHousingShellStageTransform from .spi_spine import ( UKFRSHMRCSpineLeavesStageTransform, @@ -619,6 +636,9 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: "uc_reporter_redraw": UKUCReporterRedrawStageTransform( stage=stages["uc_reporter_redraw"], engine=engine ), + "spi_benefit_coherence": UKSPIBenefitCoherenceStageTransform( + stage=stages["spi_benefit_coherence"], contract=contract + ), "uc_capital_coherence": UKUCCapitalCoherenceStageTransform( stage=stages["uc_capital_coherence"] ), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/hmrc_source_contract.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/hmrc_source_contract.py index 0bc12ee5a..3f2e96f5b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/hmrc_source_contract.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/hmrc_source_contract.py @@ -110,7 +110,6 @@ "resample_band_donor_leaves", "fit_weighted_qrf_stage2", "zero_pension_age_reports_below_state_pension_age", - "redraw_columns_from_fitted_qrf", "materialize_hmrc_income_bands_fail_closed", "classify_hmrc_income_facts_with_reviewed_fences", "gate_distributional_effective_mass", diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/local_targets.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/local_targets.py index cb93ecf0d..f629036d6 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/local_targets.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/local_targets.py @@ -24,6 +24,7 @@ UK_TENURE_SOCIAL_RENT, UK_TENURE_TYPE_TO_CATEGORY, ) +from microcosm.build.uk_runtime.uc_relationships import uc_family_child_member AREA_TYPES = ("constituency", "la") AREA_TYPE_TO_LEDGER_GEOGRAPHY_LEVEL = { @@ -295,7 +296,18 @@ def compute_household_metrics( matrix["uc_households"] = on_uc_hh if area_type == "constituency": - num_children = _values(_calculate(sim, "num_children", period)) + # The national UC-by-children rebind's composition (microcosm#1095): + # the engine's age-18 num_children moved 2.77% of UC-reporting units + # into another band, mostly by dropping 18- and 19-year-old + # qualifying young people. + claimant = _values(_calculate(sim, "is_uc_claimant", period)).astype(bool) + qualifying = _values( + _calculate( + sim, "is_child_or_qualifying_young_person_for_universal_credit", period + ) + ).astype(bool) + children = uc_family_child_member(claimant, qualifying, age) + num_children = _map_result(sim, children.astype(float), "person", "benunit") on_uc_bool = on_uc > 0 child_bands = ( ("uc_hh_0_children", num_children == 0), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/measure_simulation.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/measure_simulation.py index 58006c9dd..40e624b71 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/measure_simulation.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/measure_simulation.py @@ -18,7 +18,10 @@ load_uk_national_frame, write_uk_national_frame, ) -from microcosm.build.uk_runtime.uc_relationships import frs_uc_claimant_mask +from microcosm.build.uk_runtime.uc_relationships import ( + frs_uc_claimant_mask, + uc_family_child_member, +) from microcosm.build.uk_runtime.uc_target_measurements import ( UC_PAID_TARGET_VARIABLES, UC_TARGET_VARIABLES, @@ -152,7 +155,9 @@ def _uc_calibration_composition( ).astype(bool) if len(qualifying) != len(person): raise ValueError("UC child status must align with the person table.") - children = ~claimant & (qualifying | (person["age"].to_numpy(dtype=float) < 20)) + children = uc_family_child_member( + claimant, qualifying, person["age"].to_numpy(dtype=float) + ) child_count = pd.Series(children).groupby(member_ids).sum().reindex(ids).to_numpy() couple = claimant_count == 2 has_children = child_count > 0 diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_band_donors.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_band_donors.py index 10c4ffae4..3b04d354a 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_band_donors.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_band_donors.py @@ -45,6 +45,7 @@ from microcosm.build.uk_runtime.rowwise_geography import id_multiplier_for_values from microcosm.build.uk_runtime.spi_income import ( SPI_MINIMUM_RECIPIENT_AGE, + SPI_RECIPIENT_ROLE_COLUMN, SPIDonorAgeModel, VerifiedSPIDonorIdentity, load_spi_donor_age_model, @@ -108,7 +109,11 @@ SPI_INCOME_BAND_TAXPAYER_RESOURCE = "hmrc_itl_taxpayer_counts.json" SPI_INCOME_BAND_TAXPAYER_MEASURE = "total_taxpayer_count" SPI_INCOME_BAND_TAXPAYER_PERIOD = "build_period_tax_year" -SPI_INCOME_BAND_DONOR_CANDIDATES = "raw FRS base channel adults aged 16 and over" +#: The income stage draws only for claimants and partners (uk-data#504), so a +#: carrier is one: a dependant aged 16 to 19 would keep its twin's values. +SPI_INCOME_BAND_DONOR_CANDIDATES = ( + "raw FRS base channel claimants and partners (is_uc_claimant) aged 16 and over" +) SPI_INCOME_BAND_DONOR_PROPENSITY = ( "SPI 2022-23 FACT-weighted band share by region, sex and age band" ) @@ -461,17 +466,17 @@ def stack_spi_income_band_donors( ) -> UKSPIIncomeBandDonorResult: """Seat each band's donors and fund them from their source strata. - Carriers are adults of the raw FRS base channel, seated without - replacement with probability proportional to their household's weight - times the tape's propensity for the band given their region, sex and age - band, so the donors' composition follows the population's rather than the - sample's; a household is seated at most once across bands, the highest - band first. Every copy carries the support channel's lineage columns at - clone index 2, the synthetic flag (so the income stage draws for it), the - donor flag, its band and one carrier flag, and starts at its band's equal - weight. The mass the donors carry leaves the incumbent households of each - donor's funding stratum in proportion, so the total and every stratum's - mass are unchanged. + Carriers are claimants and partners of the raw FRS base channel aged 16 + and over, seated without replacement with probability proportional to + their household's weight times the tape's propensity for the band given + their region, sex and age band, so the donors' composition follows the + population's rather than the sample's; a household is seated at most once + across bands, the highest band first. Every copy carries the support + channel's lineage columns at clone index 2, the synthetic flag (so the + income stage draws for it), the donor flag, its band and one carrier flag, + and starts at its band's equal weight. The mass the donors carry leaves the + incumbent households of each donor's funding stratum in proportion, so the + total and every stratum's mass are unchanged. """ validate_uk_national_frame(frame) @@ -495,12 +500,17 @@ def stack_spi_income_band_donors( ("region", household, "household"), ("age", person, "person"), ("gender", person, "person"), + (SPI_RECIPIENT_ROLE_COLUMN, person, "person"), ): if column not in table.columns: raise ValueError( f"SPI income band donors require {label} column {column!r}; " "run the stage after spi_support_channel." ) + if not pd.api.types.is_bool_dtype(person[SPI_RECIPIENT_ROLE_COLUMN].dtype): + raise ValueError( + f"SPI income band donors need a boolean {SPI_RECIPIENT_ROLE_COLUMN!r}." + ) if HOUSEHOLD_IS_SPI_INCOME_BAND_DONOR in household.columns: raise ValueError("SPI income band donors were already stacked.") plan = spi_income_band_donor_plan( @@ -523,6 +533,7 @@ def stack_spi_income_band_donors( person[person_channel].eq(BASE_FRS_SUPPORT_CHANNEL) & person["person_household_id"].isin(set(base_households["household_id"])) & pd.to_numeric(person["age"], errors="coerce").ge(SPI_MINIMUM_RECIPIENT_AGE) + & person[SPI_RECIPIENT_ROLE_COLUMN] ].copy() if candidates.empty: raise ValueError("SPI income band donors found no adult FRS candidates.") diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_benefit_coherence.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_benefit_coherence.py new file mode 100644 index 000000000..0c6c72791 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_benefit_coherence.py @@ -0,0 +1,632 @@ +"""Benefit reports and take-up on SPI-channel rows (microcosm#1095, uk-data#514). + +The SPI support channel copies whole FRS households, replaces their adults' +incomes with SPI draws and re-imputes each adult's benefit reports with the +FRS-only stage-2 forests of ``hmrc_spi_income_spine``, which condition on age, +gender, region and the new incomes and see nothing of the benefit unit's +entitlement or claim history. On the 30 September national build the SPI rows +reported Income Support, Working and Child Tax Credit and income-based JSA at +2.6 to 9.1 times the FRS rate and contributory JSA at 17 times (two thirds of +its SPI reporters earning above the permitted-work limit), held 64%, 72% and +67% of the reported IIDB, AFCS and bereavement support, kept the FRS twin's +``receives_benefits_in_own_right`` (3.04m SPI persons disagreed with their own +reports) and kept the twin's early Universal Credit take-up anchor (1.51m SPI +benefit units claimed only because the twin reported Universal Credit). + +This stage runs on SPI-channel rows only, after ``uc_reporter_redraw`` (the +last writer of Universal Credit reports) and before ``uc_capital_coherence`` +and the Pension Credit and Child Benefit take-up stages, which read +qualifying-young-person status and the taxable benefits: + +- it zeroes the reports whose award needs an existing legacy claim, an + out-of-work test, or a claim the copied household's new incomes cannot + support: contributory and income-based JSA, income-related ESA, Income + Support, Working and Child Tax Credit, Severe Disablement Allowance and the + Sure Start Maternity Grant. policyengine-uk pays income-related ESA as + reported behind a capital test alone, so a kept draw paid the twin's award + whatever the copy's new incomes: on the microcosm#1095 arm A8 spine the SPI + rows held 29% of the income-related ESA reporters at design weights, and + 56% of their benefit units had incomes above GBP 12,570; +- it restores Industrial Injuries Disablement Benefit, the Armed Forces + Compensation Scheme and bereavement support from the FRS twin, since they + follow an injury, service or a death and not income; +- it re-derives the disability flags from the final reports with the FRS + stage's rule (the categories, which read only AA, DLA and PIP, are + unchanged and asserted so); +- it rebuilds ``receives_benefits_in_own_right`` from each person's own + Universal Credit, JSA and ESA reports with ``frs_education``'s rule; +- it redraws ``would_claim_uc`` for SPI benefit units as ``frs_take_up`` drew + it for the FRS units: a unit with a Universal Credit reporter claims, and the + other units in the Universal Credit age population claim as the residual of + the take-up contract's rate, on draws keyed on the SPI unit's own identity. + +Contributory ESA, the disability benefits, Carer's Allowance, State Pension +and Winter Fuel Payment keep their draws, and FRS base rows are never +modified. Contributory ESA is not income-tested, and the incapacity it needs +follows the person, whose health and disability reports the SPI copy keeps; on +the A8 spine its SPI draw sits at half the FRS rate per working-age adult, and +9.9% of its SPI reporters by weight earn above the permitted-work limit +(uk-data#514 zeroes it on a build where 41% did). +""" + +from __future__ import annotations + +from collections.abc import Mapping +from dataclasses import dataclass, field + +import numpy as np +import pandas as pd + +from microcosm.build.source_manifest import SourceStageSpec +from microcosm.build.stochastic_assignment import ( + assign_binary_with_anchored_residual, + stable_identity_uniforms, +) +from microcosm.build.uk_runtime import frs_disability +from microcosm.build.uk_runtime.frs_education import ( + BENEFITS_IN_OWN_RIGHT_REPORTED_COLUMNS, +) +from microcosm.build.uk_runtime.frs_take_up import ( + UK_UC_AGE_ELIGIBLE_AGGREGATE, + UK_UC_AGE_ELIGIBLE_METHOD, + UK_UC_AGE_ELIGIBLE_SOURCE, + UK_UC_TAKE_UP_OUTPUT, + UKTakeUpPopulationPolicy, + assert_take_up_stage_population_declaration, + uc_age_eligible_benunits, + uk_take_up_population_policy, +) +from microcosm.build.uk_runtime.national_frame import ( + uk_household_weight_kind, + uk_national_frame, + uk_time_period, + validate_uk_national_frame, +) +from microcosm.build.uk_runtime.spi_support import ( + BASE_FRS_SUPPORT_CHANNEL, + SPI_SYNTHETIC_SUPPORT_CHANNEL, + fill_support_channel_from_source, + support_channel_column, + support_source_id_column, +) +from microcosm.build.uk_runtime.take_up_contract import ( + UKTakeUpContract, + load_uk_take_up_contract, +) +from microcosm.build.uk_runtime.uc_capital_coherence import ( + _household_to_benunit_weights, +) +from microcosm.frame import Frame + +SPI_BENEFIT_COHERENCE_STAGE_NAME = "spi_benefit_coherence" +SPI_BENEFIT_COHERENCE_ROWS = "spi_synthetic_support_channel" +#: Reports whose award needs an existing legacy claim, an out-of-work test, or +#: a claim the copied household's new incomes cannot carry. Contributory ESA, +#: open to new claims and not income-tested, keeps its draw (module docstring). +SPI_ZEROED_REPORT_COLUMNS = ( + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported", +) +SPI_ZEROED_REPORT_REASON = ( + "award needs an existing legacy claim, an out-of-work test, or a claim the " + "copied household's new incomes cannot carry" +) +#: Reports that follow an injury, service or a death, not income: the SPI row +#: keeps the FRS twin's value. +SPI_RESTORED_REPORT_COLUMNS = ("iidb_reported", "afcs_reported", "bsp_reported") +SPI_RESTORED_REPORT_REASON = "follows an injury, service or a death, not income" +SPI_TWIN_LINKAGE = "person_source_id -> FRS-channel person_id" +SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT = "receives_benefits_in_own_right" +SPI_BENEFITS_IN_OWN_RIGHT_RULE = ( + "universal_credit_reported + jsa_contrib_reported + jsa_income_reported + " + "esa_contrib_reported + esa_income_reported > 0 (frs_education), SPI-channel " + "rows; FRS rows asserted unchanged" +) +SPI_DISABILITY_REFRESH_SCOPE = ( + "disability categories and flags re-derived on SPI-channel rows from the " + "final reports with the frs_disability rule at its declared year; the " + "categories, which read only AA, DLA and PIP, asserted unchanged" +) +SPI_UC_REPORTED_ANCHOR = "universal_credit_reported_anchor" +SPI_UC_TAKE_UP_RATE_KEY = "universal_credit" +SPI_UC_TAKE_UP_SEED = 0 +#: The disability flags the refresh writes; the categories read only AA, DLA +#: and PIP, which the stage keeps, so they are asserted unchanged instead. +SPI_DISABILITY_FLAG_COLUMNS = tuple( + column + for column in frs_disability.FRS_DISABILITY_OUTPUT_COLUMNS + if not column.endswith("_category") +) +SPI_BENEFIT_COHERENCE_REWRITES = ( + *SPI_ZEROED_REPORT_COLUMNS, + *SPI_RESTORED_REPORT_COLUMNS, + *SPI_DISABILITY_FLAG_COLUMNS, + SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT, + UK_UC_TAKE_UP_OUTPUT, +) + + +def spi_benefit_coherence_operations() -> tuple[tuple[str, dict[str, object]], ...]: + """The stage's operations, in order, as ``(kind, parameters)`` pairs.""" + + return ( + ( + "zero_spi_channel_reports", + { + "rows": SPI_BENEFIT_COHERENCE_ROWS, + "columns": list(SPI_ZEROED_REPORT_COLUMNS), + "reason": SPI_ZEROED_REPORT_REASON, + }, + ), + ( + "restore_spi_channel_reports_from_source", + { + "rows": SPI_BENEFIT_COHERENCE_ROWS, + "columns": list(SPI_RESTORED_REPORT_COLUMNS), + "linkage": SPI_TWIN_LINKAGE, + "reason": SPI_RESTORED_REPORT_REASON, + }, + ), + ("derive", {"scope": SPI_DISABILITY_REFRESH_SCOPE}), + ( + "derive", + { + "output": SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT, + "formula": SPI_BENEFITS_IN_OWN_RIGHT_RULE, + }, + ), + ( + "aggregate_person_to_benunit", + { + "method": "any_positive", + "consumed_only": True, + "aggregates": {SPI_UC_REPORTED_ANCHOR: "universal_credit_reported"}, + }, + ), + ( + "aggregate_person_to_benunit", + { + "method": UK_UC_AGE_ELIGIBLE_METHOD, + "consumed_only": True, + "aggregates": {UK_UC_AGE_ELIGIBLE_AGGREGATE: UK_UC_AGE_ELIGIBLE_SOURCE}, + }, + ), + ( + "assign_binary_with_anchored_residual", + { + "output": UK_UC_TAKE_UP_OUTPUT, + "draw": UK_UC_TAKE_UP_OUTPUT, + "rate_key": SPI_UC_TAKE_UP_RATE_KEY, + "anchor": SPI_UC_REPORTED_ANCHOR, + "population": UK_UC_AGE_ELIGIBLE_AGGREGATE, + "seed": SPI_UC_TAKE_UP_SEED, + "rows": SPI_BENEFIT_COHERENCE_ROWS, + }, + ), + ) + + +@dataclass(frozen=True) +class UKSPIBenefitCoherenceResult: + """Output frame and executed-effect receipt for the SPI benefit pass.""" + + frame: Frame + spi_person_rows: int + spi_benefit_units: int + zeroed: Mapping[str, Mapping[str, float]] + restored: Mapping[str, Mapping[str, float]] + disability_flags_changed: Mapping[str, int] + benefits_in_own_right: Mapping[str, float] + universal_credit_take_up: Mapping[str, float] + + def evidence(self) -> dict[str, object]: + return { + "stage": SPI_BENEFIT_COHERENCE_STAGE_NAME, + "rows": SPI_BENEFIT_COHERENCE_ROWS, + "spi_person_rows": self.spi_person_rows, + "spi_benefit_units": self.spi_benefit_units, + "zeroed": {key: dict(value) for key, value in self.zeroed.items()}, + "restored": {key: dict(value) for key, value in self.restored.items()}, + "disability_flags_changed": dict(self.disability_flags_changed), + "benefits_in_own_right": dict(self.benefits_in_own_right), + "universal_credit_take_up": dict(self.universal_credit_take_up), + "base_rows_unchanged": True, + } + + +@dataclass(frozen=True) +class UKSPIBenefitCoherenceStageTransform: + """Whole-stage callable for the SPI-channel benefit coherence pass.""" + + stage: SourceStageSpec + contract: UKTakeUpContract | None = None + population_policy: UKTakeUpPopulationPolicy | None = None + category_rates: object | None = None + flag_rates: object | None = None + last_result: UKSPIBenefitCoherenceResult | None = field(default=None, init=False) + + def __call__(self, frame: Frame) -> Frame: + assert_spi_benefit_coherence_stage_parameters(self.stage) + result = apply_spi_benefit_coherence( + frame, + contract=self.contract or load_uk_take_up_contract(), + population_policy=( + self.population_policy + or uk_take_up_population_policy(uk_time_period(frame)) + ), + category_rates=self.category_rates, + flag_rates=self.flag_rates, + ) + object.__setattr__(self, "last_result", result) + return result.frame + + @staticmethod + def output_columns() -> tuple[str, ...]: + return () + + def checkpoint_metadata(self) -> dict[str, object]: + if self.last_result is None: + raise RuntimeError("checkpoint metadata requires a completed stage run.") + return {"evidence": self.last_result.evidence()} + + +def apply_spi_benefit_coherence( + frame: Frame, + *, + contract: UKTakeUpContract, + population_policy: UKTakeUpPopulationPolicy, + category_rates: object | None = None, + flag_rates: object | None = None, +) -> UKSPIBenefitCoherenceResult: + """Zero, restore and re-derive SPI-channel reports; redraw their UC take-up.""" + + validate_uk_national_frame(frame) + person = frame.table("person").copy() + benunit = frame.table("benunit").copy() + household = frame.table("household").copy() + person_channel = support_channel_column("person") + benunit_channel = support_channel_column("benunit") + required_person = { + "person_id", + "person_benunit_id", + "person_household_id", + "age", + person_channel, + support_source_id_column("person"), + *SPI_ZEROED_REPORT_COLUMNS, + *SPI_RESTORED_REPORT_COLUMNS, + *BENEFITS_IN_OWN_RIGHT_REPORTED_COLUMNS, + *frs_disability.UK_DISABILITY_FLAG_REPORTED_COLUMNS, + *frs_disability.FRS_DISABILITY_OUTPUT_COLUMNS, + SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT, + } + missing = sorted(required_person - set(person.columns)) + if missing: + raise ValueError(f"SPI benefit coherence person columns missing: {missing}.") + missing = sorted( + {"benunit_id", benunit_channel, UK_UC_TAKE_UP_OUTPUT} - set(benunit.columns) + ) + if missing: + raise ValueError(f"SPI benefit coherence benunit columns missing: {missing}.") + channels = set(person[person_channel].unique()) + unexpected = sorted( + channels - {BASE_FRS_SUPPORT_CHANNEL, SPI_SYNTHETIC_SUPPORT_CHANNEL} + ) + if unexpected: + raise ValueError( + "SPI benefit coherence runs before any other support channel exists; " + f"found {unexpected}." + ) + spi = (person[person_channel] == SPI_SYNTHETIC_SUPPORT_CHANNEL).to_numpy() + base = ~spi + if not spi.any(): + raise ValueError("SPI benefit coherence found no SPI-channel person rows.") + rewritten = list( + dict.fromkeys( + ( + *SPI_ZEROED_REPORT_COLUMNS, + *SPI_RESTORED_REPORT_COLUMNS, + *frs_disability.FRS_DISABILITY_OUTPUT_COLUMNS, + SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT, + ) + ) + ) + # The categories are in the base-row check too: the refresh must leave + # them untouched everywhere. + before = person[rewritten].copy() + weights = _person_weights(person, household, frame.weights_for("household").values) + + zeroed: dict[str, dict[str, float]] = {} + for column in SPI_ZEROED_REPORT_COLUMNS: + values = pd.to_numeric(person[column], errors="coerce").fillna(0.0).to_numpy() + reporting = spi & (values > 0.0) + zeroed[column] = { + "rows_reporting_before": int(reporting.sum()), + "weighted_reporters_before": float(weights[reporting].sum()), + "weighted_amount_before": float((values * weights)[spi].sum()), + } + person.loc[spi, column] = 0.0 + after = pd.to_numeric(person[column], errors="coerce").fillna(0.0).to_numpy() + zeroed[column]["rows_reporting_after"] = int((spi & (after > 0.0)).sum()) + + twin = person.loc[base, ["person_id", *SPI_RESTORED_REPORT_COLUMNS]] + restored_frame = fill_support_channel_from_source( + person, + twin, + entity="person", + columns=SPI_RESTORED_REPORT_COLUMNS, + ) + restored: dict[str, dict[str, float]] = {} + for column in SPI_RESTORED_REPORT_COLUMNS: + old = pd.to_numeric(person[column], errors="coerce").fillna(0.0).to_numpy() + new = ( + pd.to_numeric(restored_frame[column], errors="coerce") + .fillna(0.0) + .to_numpy() + ) + restored[column] = { + "rows_changed": int((spi & ~np.isclose(old, new)).sum()), + "weighted_amount_before": float((old * weights)[spi].sum()), + "weighted_amount_after": float((new * weights)[spi].sum()), + "weighted_reporters_before": float(weights[spi & (old > 0.0)].sum()), + "weighted_reporters_after": float(weights[spi & (new > 0.0)].sum()), + } + person[column] = restored_frame[column].to_numpy() + restored_check = fill_support_channel_from_source( + person, + person.loc[base, ["person_id", *SPI_RESTORED_REPORT_COLUMNS]], + entity="person", + columns=SPI_RESTORED_REPORT_COLUMNS, + ) + for column in SPI_RESTORED_REPORT_COLUMNS: + restored[column]["rows_differing_from_twin_after"] = int( + ( + spi + & ~np.isclose( + pd.to_numeric(person[column], errors="coerce").fillna(0.0), + pd.to_numeric(restored_check[column], errors="coerce").fillna(0.0), + ) + ).sum() + ) + + flags_changed = _refresh_disability( + person, spi=spi, category_rates=category_rates, flag_rates=flag_rates + ) + + own_right_rule = ( + person[list(BENEFITS_IN_OWN_RIGHT_REPORTED_COLUMNS)] + .apply(pd.to_numeric, errors="coerce") + .fillna(0.0) + .sum(axis=1) + .gt(0.0) + .to_numpy() + ) + stored_own_right = person[SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT].astype(bool).to_numpy() + drifted = base & (own_right_rule != stored_own_right) + if drifted.any(): + raise ValueError( + f"{int(drifted.sum())} FRS-channel person(s) carry " + f"{SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT} that disagrees with their own " + "reports; the frs_education rule and an upstream stage have drifted." + ) + own_right = { + "spi_rows_changed": int((spi & (own_right_rule != stored_own_right)).sum()), + "spi_true_before": int((spi & stored_own_right).sum()), + "spi_true_after": int((spi & own_right_rule).sum()), + "weighted_spi_changed": float( + weights[spi & (own_right_rule != stored_own_right)].sum() + ), + } + person.loc[spi, SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT] = own_right_rule[spi] + person[SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT] = person[ + SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT + ].astype(bool) + own_right["mismatches_after"] = int( + ( + person[SPI_BENEFITS_IN_OWN_RIGHT_OUTPUT].to_numpy(dtype=bool) + != own_right_rule + ).sum() + ) + + for column in rewritten: + unchanged = before.loc[base, column].equals(person.loc[base, column]) + if not unchanged: + raise ValueError( + f"SPI benefit coherence changed FRS-channel {column!r}; base rows " + "are never modified." + ) + + benunit, take_up = _redraw_spi_uc_take_up( + person=person, + benunit=benunit, + household=household, + household_weights=frame.weights_for("household").values, + contract=contract, + population_policy=population_policy, + ) + result = uk_national_frame( + person=person, + benunit=benunit, + household=household, + time_period=uk_time_period(frame), + weight_kind=uk_household_weight_kind(frame), + household_weights=frame.weights_for("household").values, + mass_log=frame.mass_log, + ) + validate_uk_national_frame(result) + return UKSPIBenefitCoherenceResult( + frame=result, + spi_person_rows=int(spi.sum()), + spi_benefit_units=int(take_up["spi_benefit_units"]), + zeroed=zeroed, + restored=restored, + disability_flags_changed=flags_changed, + benefits_in_own_right=own_right, + universal_credit_take_up=take_up, + ) + + +def _redraw_spi_uc_take_up( + *, + person: pd.DataFrame, + benunit: pd.DataFrame, + household: pd.DataFrame, + household_weights: np.ndarray, + contract: UKTakeUpContract, + population_policy: UKTakeUpPopulationPolicy, +) -> tuple[pd.DataFrame, dict[str, float]]: + benunit = benunit.copy() + spi_units = ( + benunit[support_channel_column("benunit")] == SPI_SYNTHETIC_SUPPORT_CHANNEL + ).to_numpy() + reported = ( + pd.to_numeric(person["universal_credit_reported"], errors="coerce").fillna(0.0) + > 0.0 + ) + reporter = ( + benunit["benunit_id"] + .isin(set(person.loc[reported, "person_benunit_id"])) + .to_numpy(dtype=bool) + ) + population = uc_age_eligible_benunits(person, benunit, population_policy) + rate = contract.rate(SPI_UC_TAKE_UP_RATE_KEY) + draws = stable_identity_uniforms( + benunit.loc[spi_units, "benunit_id"].to_numpy(), + seed=SPI_UC_TAKE_UP_SEED, + salt=UK_UC_TAKE_UP_OUTPUT, + ) + redrawn = assign_binary_with_anchored_residual( + draws, + rate, + anchor=reporter[spi_units], + population=population[spi_units], + ) + previous = benunit[UK_UC_TAKE_UP_OUTPUT].fillna(False).astype(bool).to_numpy() + weights = _household_to_benunit_weights( + benunit, + person=person, + household=household, + household_weights=household_weights, + ) + after = previous.copy() + after[spi_units] = redrawn + benunit[UK_UC_TAKE_UP_OUTPUT] = after + spi_population = spi_units & population + receipt = { + "rate_key": SPI_UC_TAKE_UP_RATE_KEY, + "rate": float(rate), + "seed": SPI_UC_TAKE_UP_SEED, + "population_state_pension_age": int(population_policy.state_pension_age), + "spi_benefit_units": int(spi_units.sum()), + "spi_population_units": int(spi_population.sum()), + "spi_reporter_units": int((spi_units & reporter).sum()), + "spi_claiming_before": int((spi_units & previous).sum()), + "spi_claiming_after": int((spi_units & after).sum()), + "set_true": int((spi_units & ~previous & after).sum()), + "set_false": int((spi_units & previous & ~after).sum()), + "weighted_spi_claiming_before": float(weights[spi_units & previous].sum()), + "weighted_spi_claiming_after": float(weights[spi_units & after].sum()), + "weighted_spi_population": float(weights[spi_population].sum()), + "reporters_not_claiming": int((spi_units & reporter & ~after).sum()), + "outside_population_non_reporters_claiming": int( + (spi_units & ~population & ~reporter & after).sum() + ), + } + return benunit, receipt + + +def _refresh_disability( + person: pd.DataFrame, + *, + spi: np.ndarray, + category_rates: object | None, + flag_rates: object | None, +) -> dict[str, int]: + if category_rates is None or flag_rates is None: + from microcosm.build.uk_runtime.frs_release import resolve_uk_year_rule + + year = resolve_uk_year_rule(frs_disability.YEAR_RULE) + if category_rates is None: + category_rates = frs_disability.uk_dwp_disability_category_rates(year) + if flag_rates is None: + flag_rates = frs_disability.uk_dwp_disability_flag_rates(year) + rows = person.loc[spi] + derived = frs_disability.derive_frs_disability( + rows, category_rates=category_rates, flag_rates=flag_rates + ) + changed: dict[str, int] = {} + for column in frs_disability.FRS_DISABILITY_OUTPUT_COLUMNS: + new = derived[column].to_numpy() + old = rows[column].to_numpy() + moved = int((new != old).sum()) + if column.endswith("_category"): + if moved: + raise ValueError( + f"SPI benefit coherence moved {moved} {column!r} value(s); the " + "categories read only AA, DLA and PIP, which this stage keeps." + ) + continue + changed[column] = moved + person.loc[spi, column] = new.astype(bool) + return changed + + +def _person_weights( + person: pd.DataFrame, household: pd.DataFrame, household_weights: np.ndarray +) -> np.ndarray: + by_household = pd.Series( + np.asarray(household_weights, dtype=float), + index=household["household_id"].to_numpy(), + ) + weights = person["person_household_id"].map(by_household) + if weights.isna().any(): + raise ValueError("SPI benefit coherence persons must map to a household.") + return weights.to_numpy(dtype=float) + + +def assert_spi_benefit_coherence_stage_parameters(stage: SourceStageSpec) -> None: + """Refuse a manifest whose operations differ from the code's.""" + + if stage.stage != SPI_BENEFIT_COHERENCE_STAGE_NAME: + raise ValueError( + f"SPI benefit coherence received stage {stage.stage!r}, expected " + f"{SPI_BENEFIT_COHERENCE_STAGE_NAME!r}." + ) + expected = [ + (kind, dict(parameters)) + for kind, parameters in spi_benefit_coherence_operations() + ] + actual = [ + (operation.kind, dict(operation.parameters)) for operation in stage.operations + ] + if actual != expected: + raise ValueError( + f"{SPI_BENEFIT_COHERENCE_STAGE_NAME} operations drifted: expected " + f"{expected}, got {actual}." + ) + assert_take_up_stage_population_declaration(stage) + if stage.outputs != () or tuple(stage.rewrites) != SPI_BENEFIT_COHERENCE_REWRITES: + raise ValueError( + f"{SPI_BENEFIT_COHERENCE_STAGE_NAME} must declare no new outputs and " + f"exactly the rewrites {SPI_BENEFIT_COHERENCE_REWRITES}." + ) + + +__all__ = [ + "SPI_BENEFIT_COHERENCE_REWRITES", + "SPI_DISABILITY_FLAG_COLUMNS", + "SPI_BENEFIT_COHERENCE_STAGE_NAME", + "SPI_RESTORED_REPORT_COLUMNS", + "SPI_ZEROED_REPORT_COLUMNS", + "UKSPIBenefitCoherenceResult", + "UKSPIBenefitCoherenceStageTransform", + "apply_spi_benefit_coherence", + "assert_spi_benefit_coherence_stage_parameters", + "spi_benefit_coherence_operations", +] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_income.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_income.py index a07c5bc87..3775f3aad 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_income.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_income.py @@ -74,6 +74,12 @@ # FRS dependent-child status can extend to ages 16-19; this guard is an age # support boundary, not a crosswalk to that household-composition definition. SPI_MINIMUM_RECIPIENT_AGE = 16 +#: The tape samples taxpayers in their own right, so its draws go to the FRS +#: benefit unit's claimant or partner; a dependent child aged 16 to 19 is +#: neither and keeps every value of its FRS twin (uk-data#504, microcosm#1095). +#: The column persists the FRS adult-file role from +#: ``uc_relationships.frs_uc_claimant_mask``. +SPI_RECIPIENT_ROLE_COLUMN = "is_uc_claimant" SPI_DONOR_INCOME_YEAR = 2022 # Use the pinned engine's variable-specific indices. None explicitly retains # nominal amounts where no same-scope indexed mapping has been reviewed; @@ -535,6 +541,7 @@ class UKSPIIncomeImputationResult: band_donor_resample: Mapping[str, object] | None = None donor_age_draw: Mapping[str, object] | None = None state_pension_age_guard: tuple[Mapping[str, object], ...] = () + recipient_domain: Mapping[str, object] | None = None @dataclass(frozen=True) @@ -635,7 +642,6 @@ def impute_uk_spi_income_support( verified_donor: VerifiedSPIDonorIdentity | None = None, donor_table: pd.DataFrame | None = None, initialize_frs_channel_columns: Mapping[str, float] | None = None, - stage1_base_redraw_columns: Sequence[str] = (), condition_on_state_pension_receipt: bool = False, rebase_income_to_build_period: bool = False, band_donor_resample: Mapping[str, object] | None = None, @@ -732,11 +738,32 @@ def impute_uk_spi_income_support( spi_channel_people = person[person_channel] == SPI_SYNTHETIC_SUPPORT_CHANNEL if not spi_channel_people.any(): raise ValueError("SPI support has no person rows to impute.") - _require_columns(person, ("age",), label="SPI recipient age domain") + _require_columns( + person, ("age", SPI_RECIPIENT_ROLE_COLUMN), label="SPI recipient domain" + ) _require_finite_numeric(person[["age"]], label="SPI recipient ages") - spi_people = spi_channel_people & person.age.ge(SPI_MINIMUM_RECIPIENT_AGE) + if not pd.api.types.is_bool_dtype(person[SPI_RECIPIENT_ROLE_COLUMN].dtype): + raise ValueError( + f"SPI recipient role column {SPI_RECIPIENT_ROLE_COLUMN!r} must be boolean." + ) + # Both forests are queried over the age domain, the recipient rule before + # uk-data#504, so each recipient keeps the draw it has always had; the + # rows of dependants aged 16 to 19 are then discarded. + spi_age_domain = spi_channel_people & person.age.ge(SPI_MINIMUM_RECIPIENT_AGE) + spi_people = spi_age_domain & person[SPI_RECIPIENT_ROLE_COLUMN] if not spi_people.any(): raise ValueError("SPI support has no recipients in the donor age domain.") + recipient_domain = { + "minimum_age": SPI_MINIMUM_RECIPIENT_AGE, + "role_column": SPI_RECIPIENT_ROLE_COLUMN, + "recipient_rows": int(spi_people.sum()), + "dependant_rows_kept_on_twin_values": int((spi_age_domain & ~spi_people).sum()), + "dependant_weight_kept_on_twin_values": float( + _person_household_weights(person, household) + .loc[spi_age_domain & ~spi_people] + .sum() + ), + } base_people = person[person_channel] == BASE_FRS_SUPPORT_CHANNEL if not base_people.any(): raise ValueError("SPI support has no FRS base rows.") @@ -746,15 +773,6 @@ def impute_uk_spi_income_support( base_people=base_people, columns=initialize_frs_channel_columns, ) - base_redraw_columns = tuple(stage1_base_redraw_columns) - unknown_redraw = sorted( - set(base_redraw_columns) - set(SPI_INCOME_QRF_OUTPUT_COLUMNS) - ) - if unknown_redraw: - raise ValueError( - "SPI stage-1 base redraw columns must be stage-1 QRF outputs; " - f"unknown column(s): {unknown_redraw}." - ) person = _seed_frs_hmrc_auxiliary_leaves(person, spi_people=spi_people) recipient_predictors = _stage1_query_predictors( @@ -784,14 +802,14 @@ def impute_uk_spi_income_support( expected=SPI_INCOME_QRF_OUTPUT_COLUMNS, label="SPI stage-1", ) - # Hold the existing RNG stream fixed: the fitted forest is also used - # later for the base-channel dividend redraw. Consume the legacy query - # shape, then discard under-age draws before any assignment. This keeps - # adult stage-1 draw pool and the base redraw stream identical. - adult_positions = ( - person.loc[spi_channel_people, "age"].ge(SPI_MINIMUM_RECIPIENT_AGE).to_numpy() - ) - stage1_draws = stage1_draws.iloc[np.flatnonzero(adult_positions)].copy() + # Hold the existing RNG stream fixed: query the legacy shape (every + # SPI-channel person), then discard the draws outside the recipient domain + # (children, and dependants aged 16 to 19: uk-data#504) before any + # assignment, so each recipient keeps the draw it has always had. + # FRS-channel rows keep their own reported incomes, dividends included + # (uk-data#498, microcosm#1095). + recipient_positions = spi_people.loc[spi_channel_people].to_numpy(dtype=bool) + stage1_draws = stage1_draws.iloc[np.flatnonzero(recipient_positions)].copy() income_uprating = None uprating_factors = dict.fromkeys(SPI_INCOME_QRF_OUTPUT_COLUMNS, 1.0) if rebase_income_to_build_period: @@ -879,11 +897,17 @@ def impute_uk_spi_income_support( household, income_predictors=income_predictors, ) + # Queried over the age domain like stage 1; a dependant's row conditions + # on its twin's values and is discarded below, and the draws consume the + # RNG stream row by row, so no recipient's draw depends on it. target_predictors = _person_predictors( - person.loc[spi_people], + person.loc[spi_age_domain], household, income_predictors=income_predictors, ) + stage2_recipient_positions = np.flatnonzero( + spi_people.loc[spi_age_domain].to_numpy(dtype=bool) + ) pension_bridge = None if condition_on_state_pension_receipt: # A receipt indicator is a predictive bridge, not an assertion that @@ -892,7 +916,7 @@ def impute_uk_spi_income_support( # to a stage-1 vector whose HMRC pension leaf is already determined. train_receipt = person.loc[training_people, "state_pension_reported"].gt(0) target_receipt = person.loc[ - spi_people, SPI_HMRC_STATE_PENSION_INCOME_COLUMN + spi_age_domain, SPI_HMRC_STATE_PENSION_INCOME_COLUMN ].gt(0) train_predictors["state_pension_receipt"] = train_receipt.astype(float) target_predictors["state_pension_receipt"] = target_receipt.astype(float) @@ -900,7 +924,9 @@ def impute_uk_spi_income_support( "training_source": "state_pension_reported > 0", "recipient_source": "hmrc_spi_state_pension_income > 0", "training_positive_rows": int(train_receipt.sum()), - "recipient_positive_rows": int(target_receipt.sum()), + "recipient_positive_rows": int( + target_receipt.iloc[stage2_recipient_positions].sum() + ), } encoded_train, encoded_target = _encode_predictor_pair( train_predictors, @@ -931,6 +957,7 @@ def impute_uk_spi_income_support( expected=stage2_outputs, label="FRS-only stage-2", ) + stage2_draws = stage2_draws.iloc[stage2_recipient_positions].copy() if (stage2_draws.to_numpy(dtype=np.float64) < 0.0).any(): raise ValueError("FRS-only stage-2 produced negative non-negative outputs.") for column in stage2_outputs: @@ -949,35 +976,6 @@ def impute_uk_spi_income_support( ) guard_receipts.append(receipt) - if base_redraw_columns: - base_predictors = _stage1_query_predictors(person.loc[base_people], household) - _, encoded_base = _encode_predictor_pair( - donor[["age", "gender", "region"]], - base_predictors, - ) - base_draws = stage1.predict(encoded_base) - _validate_predictions( - base_draws, - expected=SPI_INCOME_QRF_OUTPUT_COLUMNS, - label="SPI stage-1 base redraw", - ) - if ( - base_draws[list(base_redraw_columns)] - .to_numpy(dtype=np.float64) - .min(initial=0.0) - < 0.0 - ): - raise ValueError("SPI stage-1 base redraw produced negative outputs.") - for column in base_redraw_columns: - # This redraw also uses adult SPI donors. Preserve observed FRS - # child dividends, while consuming the same base query stream. - base_adults = ( - person.loc[base_people, "age"].ge(SPI_MINIMUM_RECIPIENT_AGE).to_numpy() - ) - person.loc[ - base_people & person.age.ge(SPI_MINIMUM_RECIPIENT_AGE), column - ] = base_draws[column].to_numpy()[base_adults] * uprating_factors[column] - tax_free = person.loc[spi_people, "tax_free_savings_income"].to_numpy( dtype=np.float64 ) @@ -1011,6 +1009,7 @@ def impute_uk_spi_income_support( band_donor_resample=band_donor_receipt, donor_age_draw=donor_age_draw, state_pension_age_guard=tuple(guard_receipts), + recipient_domain=recipient_domain, ) @@ -1111,9 +1110,14 @@ def _resample_band_donor_leaves( for column in ("total_income", "is_composite", "region", "FACT"): if column not in donor.columns: raise ValueError(f"band donor resample needs donor column {column!r}.") - carriers = person[SPI_INCOME_BAND_CARRIER_COLUMN].astype(bool) & spi_people.astype( - bool - ) + flagged = person[SPI_INCOME_BAND_CARRIER_COLUMN].astype(bool) + if (flagged & ~spi_people.astype(bool)).any(): + raise ValueError( + "band donor carriers must be SPI recipients; a carrier outside the " + "recipient domain would keep its twin's values and leave its band " + "unfilled." + ) + carriers = flagged if not carriers.any(): raise ValueError("band donor resample found no reserved carriers.") by_household = household.set_index("household_id") diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_spine.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_spine.py index cf3100703..8c770ee31 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_spine.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_spine.py @@ -63,6 +63,7 @@ SPI_INCOME_BAND_DONOR_LEAF_DRAW_SALT, SPI_INCOME_UPRATING_VARIABLES, SPI_MINIMUM_RECIPIENT_AGE, + SPI_RECIPIENT_ROLE_COLUMN, SPI_SOURCE_TI_FORMULA, SPI_STAGE2_REVIEWED_ABSENT_OUTPUTS, UKSPIIncomeImputationResult, @@ -247,11 +248,16 @@ and column not in (FRS_HMRC_PAY_COLUMN, FRS_HMRC_UBISJA_COLUMN, FRS_HMRC_INCPBEN_COLUMN) ) +#: Both forests are queried over every SPI-channel person aged 16 and over, +#: and the dependants' rows are discarded (uk-data#504, microcosm#1095). +SPI_SPINE_STAGE2_TARGET_POPULATION = ( + "spi_synthetic_support_channel claimants and partners (is_uc_claimant) " + "aged 16 and over" +) SPI_SPINE_FRS_CHANNEL_INITIALIZATION = { "gift_aid": 0.0, "charitable_investment_gifts": 0.0, } -SPI_SPINE_BASE_REDRAW_COLUMNS = ("dividend_income",) SPI_SPINE_SUPPORT_CHANNELS = {"base": "frs", "synthetic": SPI_SYNTHETIC_SUPPORT_CHANNEL} SPI_SPINE_PRECLONE_GATE_NAME = "e7_spi_synthetic_preclone" #: The reviewed SPI-channel prior share of households with a member at or over @@ -314,6 +320,8 @@ def evidence(self) -> dict[str, object]: self.imputation.reviewed_absent_stage2_outputs ), "recipient_minimum_age": SPI_MINIMUM_RECIPIENT_AGE, + "recipient_role_column": SPI_RECIPIENT_ROLE_COLUMN, + "recipient_domain": self.imputation.recipient_domain, "pension_receipt_bridge": self.imputation.pension_receipt_bridge, "income_uprating": self.imputation.income_uprating, "band_donor_resample": self.imputation.band_donor_resample, @@ -656,7 +664,6 @@ def __call__(self, frame: Frame) -> Frame: assert_frs_hmrc_auxiliary_crosswalk_available(tables["person"]) support = _support_result_from_frame(frame, tables) stage1_op = _operation(self.stage, "fit_weighted_qrf_stage1") - redraw_op = _operation(self.stage, "redraw_columns_from_fitted_qrf") resample_op = _optional_operation(self.stage, "resample_band_donor_leaves") band_donor_resample = ( None @@ -710,7 +717,6 @@ def __call__(self, frame: Frame) -> Frame: initialize_frs_channel_columns=stage1_op.parameters[ "initialize_frs_channel_columns" ], - stage1_base_redraw_columns=redraw_op.parameters["columns"], rebase_income_to_build_period=stage1_op.parameters[ "rebase_income_to_build_period" ], @@ -1074,7 +1080,12 @@ def _assert_income_stage_parameters( ) -> None: stage1 = _operation(stage, "fit_weighted_qrf_stage1") stage2 = _operation(stage, "fit_weighted_qrf_stage2") - redraw = _operation(stage, "redraw_columns_from_fitted_qrf") + if _optional_operation(stage, "redraw_columns_from_fitted_qrf") is not None: + raise ValueError( + "SPI income stage must not redraw FRS-channel incomes from the SPI " + "forest: FRS respondents keep their reported dividends " + "(uk-data#498, microcosm#1095)." + ) effective_mass = _operation(stage, "gate_distributional_effective_mass") if stage1.parameters.get("seed") != seed: raise ValueError("SPI income stage-1 seed drifted from the reviewed value.") @@ -1095,6 +1106,11 @@ def _assert_income_stage_parameters( raise ValueError("SPI income stage-1 predictors drifted.") if stage1.parameters.get("recipient_minimum_age") != SPI_MINIMUM_RECIPIENT_AGE: raise ValueError("SPI income recipient age domain drifted.") + if stage1.parameters.get("recipient_role_column") != SPI_RECIPIENT_ROLE_COLUMN: + raise ValueError( + "SPI income recipient role drifted: the tape's draws go to FRS " + "claimants and partners only (uk-data#504, microcosm#1095)." + ) if stage1.parameters.get("rebase_income_to_build_period") is not True: raise ValueError("SPI income build-year rebasing drifted.") if stage1.parameters.get("donor_income_period") != SPI_DONOR_INCOME_YEAR: @@ -1111,17 +1127,13 @@ def _assert_income_stage_parameters( raise ValueError("SPI income FRS-channel initialization map drifted.") if tuple(stage2.parameters.get("predictors", ())) != SPI_SPINE_STAGE2_PREDICTORS: raise ValueError("SPI income stage-2 predictors drifted.") + if stage2.parameters.get("target_population") != SPI_SPINE_STAGE2_TARGET_POPULATION: + raise ValueError("SPI income stage-2 target population drifted.") if tuple(stage2.parameters.get("outputs", ())) != SPI_SPINE_STAGE2_OUTPUT_COLUMNS: raise ValueError("SPI income stage-2 outputs drifted.") reviewed_absent = stage2.parameters.get("reviewed_absent_outputs", {}) if set(reviewed_absent) != set(SPI_STAGE2_REVIEWED_ABSENT_OUTPUTS): raise ValueError("SPI income stage-2 reviewed-absent outputs drifted.") - if redraw.parameters.get("fit") != "stage1": - raise ValueError("SPI income base redraw must use the stage-1 fit.") - if redraw.parameters.get("rows") != "base_support_channel": - raise ValueError("SPI income base redraw must target the base support channel.") - if tuple(redraw.parameters.get("columns", ())) != SPI_SPINE_BASE_REDRAW_COLUMNS: - raise ValueError("SPI income base redraw columns drifted.") if ( tuple(effective_mass.parameters.get("columns", ())) != SPI_SPINE_EFFECTIVE_MASS_COLUMNS diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py index 2fd730777..d7d805a9b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py @@ -141,6 +141,9 @@ from microcosm.build.uk_runtime.spi_band_donors import ( UKSPIIncomeBandDonorStageTransform, ) +from microcosm.build.uk_runtime.spi_benefit_coherence import ( + UKSPIBenefitCoherenceStageTransform, +) from microcosm.build.uk_runtime.spi_housing_shell import ( UKSPIHousingShellStageTransform, ) @@ -1524,6 +1527,10 @@ def prepare_uk_spine_execution( stage=stages_by_name["uc_reporter_redraw"], engine=engine, ) + if "spi_benefit_coherence" in stage_names: + implementations["spi_benefit_coherence"] = UKSPIBenefitCoherenceStageTransform( + stage=stages_by_name["spi_benefit_coherence"] + ) if "uc_capital_coherence" in stage_names: implementations["uc_capital_coherence"] = UKUCCapitalCoherenceStageTransform( stage=stages_by_name["uc_capital_coherence"] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py index 4b4d0da3a..2f2642bf1 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/stage_health.py @@ -47,6 +47,8 @@ def uk_stage_health_gate( return _pension_credit_take_up_gate(stage, evidence, parameters) if check == "child_benefit_take_up": return _child_benefit_take_up_gate(stage, evidence, parameters) + if check == "spi_benefit_coherence": + return _spi_benefit_coherence_gate(stage, evidence, parameters) if check == "source_signal": return _source_signal_gate(stage, evidence, parameters) if check == "age_tail_targets": @@ -1011,6 +1013,76 @@ def _pension_credit_take_up_gate( ) +def _spi_benefit_coherence_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """SPI-channel benefit reports and take-up are coherent (microcosm#1095). + + Structural zeros only: no SPI row keeps a zeroed report, every restored + report equals the FRS twin's, no person's ``receives_benefits_in_own_right`` + disagrees with their own reports, base rows are unchanged, every SPI unit + with a Universal Credit reporter claims, and no SPI unit outside the + Universal Credit age population claims without reporting. + """ + + check = "spi_benefit_coherence" + failures: list[str] = [] + zeroed = _mapping(evidence.get("zeroed"), label=f"{stage}.zeroed") + restored = _mapping(evidence.get("restored"), label=f"{stage}.restored") + own_right = _mapping( + evidence.get("benefits_in_own_right"), label=f"{stage}.benefits_in_own_right" + ) + take_up = _mapping( + evidence.get("universal_credit_take_up"), + label=f"{stage}.universal_credit_take_up", + ) + for column in parameters["zeroed_columns"]: + receipt = zeroed.get(column) + if not isinstance(receipt, Mapping): + failures.append(f"{stage}: the receipt does not record zeroing {column}.") + elif int(receipt.get("rows_reporting_after", -1)) != 0: + failures.append(f"{stage}: SPI rows still report {column}.") + for column in parameters["restored_columns"]: + receipt = restored.get(column) + if not isinstance(receipt, Mapping): + failures.append(f"{stage}: the receipt does not record restoring {column}.") + elif int(receipt.get("rows_differing_from_twin_after", -1)) != 0: + failures.append(f"{stage}: SPI {column} differs from the FRS twin.") + if int(own_right.get("mismatches_after", -1)) != 0: + failures.append( + f"{stage}: receives_benefits_in_own_right disagrees with own reports." + ) + if evidence.get("base_rows_unchanged") is not True: + failures.append(f"{stage}: base rows are not recorded as unchanged.") + for key, label in ( + ("reporters_not_claiming", "SPI Universal Credit reporters not claiming"), + ( + "outside_population_non_reporters_claiming", + "SPI units outside the Universal Credit population claiming", + ), + ): + if int(take_up.get(key, -1)) != 0: + failures.append(f"{stage}: {label}: {take_up.get(key)}.") + details = { + "zeroed": { + column: _mapping(zeroed.get(column, {}), label=f"{stage}.zeroed").get( + "rows_reporting_before" + ) + for column in parameters["zeroed_columns"] + }, + "spi_claiming_before": take_up.get("spi_claiming_before"), + "spi_claiming_after": take_up.get("spi_claiming_after"), + "own_right_changed": own_right.get("spi_rows_changed"), + } + return ( + _fail(stage, check, failures, details) + if failures + else _pass(stage, check, details) + ) + + def _spi_income_spine_gate( stage: str, evidence: Mapping[str, object], diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_capital_coherence.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_capital_coherence.py index dfce66e6c..81fe9b30c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_capital_coherence.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_capital_coherence.py @@ -14,6 +14,7 @@ from __future__ import annotations +from collections.abc import Mapping from dataclasses import dataclass, field import numpy as np @@ -34,6 +35,8 @@ support_channel_column, ) from microcosm.build.uk_runtime.uc_relationships import ( + UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS, + benunit_financial_investment_income, frs_uc_couple_mask, ) from microcosm.frame import Frame @@ -42,6 +45,32 @@ UC_CAPITAL_REDRAW_SEED = 0 UC_CAPITAL_REDRAW_SALT = UC_CAPITAL_REDRAW_OUTPUT UC_CAPITAL_COHERENCE_OUTPUT_COLUMNS = ("uc_reported_capital",) +#: Every SPI benefit unit is redrawn: the channel's incomes are SPI draws, +#: so a copied FRS capital answer no longer belongs to the unit (uk-data#495, +#: microcosm#1095). Donors are the base units with an available answer. +UC_CAPITAL_REDRAW_ROWS = "spi_channel" +UC_CAPITAL_REDRAW_DONOR_ROWS = "base_frs_with_available_capital" +UC_CAPITAL_REPORTER_STATUS = "universal_credit_reported_anchor" +UC_CAPITAL_INVESTMENT_INCOME = ( + " + ".join(UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS) + + ", summed over benefit-unit members" +) +#: Upper edges of the investment-income bands: none, then up to the income +#: GBP 6,000, 16,000, 50,000 and 200,000 of capital yield at 4%, then above. +UC_CAPITAL_INCOME_BAND_EDGES = (0.0, 240.0, 640.0, 2_000.0, 8_000.0) +UC_CAPITAL_IMPLIED_YIELD = 0.04 +UC_CAPITAL_MINIMUM_CELL_DONORS = 20 +#: The declared order in which a cell short of donors widens; reporter status +#: is never coarsened. +UC_CAPITAL_COARSENING = ( + "merge dependent-children bands", + "drop couple status", + "merge adjacent investment-income bands", + "reporter status only", +) +_UC_CAPITAL_LEVELS = ("exact_cell", *UC_CAPITAL_COARSENING) +#: The UC capital limits the receipt measures the redraw against. +_UC_CAPITAL_RECEIPT_LIMITS = (6_000.0, 16_000.0) @dataclass(frozen=True) @@ -52,6 +81,11 @@ class UKUCCapitalCoherenceResult: post_fill_reporter_count: int redrawn_spi_reporter_count: int refreshed_would_claim_count: int + redrawn_spi_benefit_units: int = 0 + coarsening_levels: Mapping[str, int] = field(default_factory=dict) + capital_against_investment_income: Mapping[str, object] = field( + default_factory=dict + ) def evidence(self) -> dict[str, object]: """Return JSON-safe stage evidence.""" @@ -60,9 +94,15 @@ def evidence(self) -> dict[str, object]: "stage": "uc_capital_coherence", "post_fill_reporter_count": self.post_fill_reporter_count, "redrawn_spi_reporter_count": self.redrawn_spi_reporter_count, + "redrawn_spi_benefit_units": self.redrawn_spi_benefit_units, "refreshed_would_claim_count": self.refreshed_would_claim_count, "redraw_seed": UC_CAPITAL_REDRAW_SEED, "redraw_salt": UC_CAPITAL_REDRAW_SALT, + "minimum_cell_donors": UC_CAPITAL_MINIMUM_CELL_DONORS, + "coarsening_levels": dict(self.coarsening_levels), + "capital_against_investment_income": dict( + self.capital_against_investment_income + ), } @@ -71,11 +111,14 @@ class UKUCCapitalCoherenceStageTransform: """Redraw SPI reporter capital and refresh UC take-up after SPI income.""" stage: SourceStageSpec + #: Synthetic fixtures too small for the declared donor floor pass a lower + #: one; every build runs the declared ``UC_CAPITAL_MINIMUM_CELL_DONORS``. + minimum_cell_donors: int = UC_CAPITAL_MINIMUM_CELL_DONORS last_result: UKUCCapitalCoherenceResult | None = field(default=None, init=False) def __call__(self, frame: Frame) -> Frame: _assert_stage_parameters(self.stage) - result = cohere_uc_capital(frame) + result = cohere_uc_capital(frame, minimum_cell_donors=self.minimum_cell_donors) object.__setattr__(self, "last_result", result) return result.frame @@ -91,7 +134,9 @@ def checkpoint_metadata(self) -> dict[str, object]: return {"evidence": self.last_result.evidence()} -def cohere_uc_capital(frame: Frame) -> UKUCCapitalCoherenceResult: +def cohere_uc_capital( + frame: Frame, *, minimum_cell_donors: int = UC_CAPITAL_MINIMUM_CELL_DONORS +) -> UKUCCapitalCoherenceResult: """Make late SPI UC receipt, FRS capital, and take-up flags coherent.""" validate_uk_national_frame(frame) @@ -100,7 +145,12 @@ def cohere_uc_capital(frame: Frame) -> UKUCCapitalCoherenceResult: household = frame.table("household").copy() _require_columns( person, - ("person_benunit_id", "person_household_id", "universal_credit_reported"), + ( + "person_benunit_id", + "person_household_id", + "universal_credit_reported", + *UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS, + ), label="person", ) _require_columns( @@ -138,18 +188,33 @@ def cohere_uc_capital(frame: Frame) -> UKUCCapitalCoherenceResult: spi = channel.eq(SPI_SYNTHETIC_SUPPORT_CHANNEL).to_numpy(dtype=bool) if np.any(~(base | spi)): raise ValueError("UC capital coherence requires only FRS and SPI channels.") - redraw = spi & reporter + investment = benunit_financial_investment_income(person, benunit) + weights = _household_to_benunit_weights( + benunit, + person=person, + household=household, + household_weights=frame.weights_for("household").values, + ) + receipt_before = _capital_against_investment_income( + capital, investment, weights, base=base, spi=spi, reporter=reporter + ) + redraw = spi + levels: dict[str, int] = dict.fromkeys(_UC_CAPITAL_LEVELS, 0) if redraw.any(): - _redraw_spi_reporter_capital( + levels = _redraw_spi_capital( benunit, person=person, - household=household, - household_weights=frame.weights_for("household").values, + weights=weights, reporter=reporter, base=base, redraw=redraw, capital=capital, + investment=investment, + minimum_cell_donors=minimum_cell_donors, ) + receipt_after = _capital_against_investment_income( + capital, investment, weights, base=base, spi=spi, reporter=reporter + ) previous_would_claim = _boolean_values(benunit["would_claim_uc"]) refreshed_would_claim = previous_would_claim | reporter @@ -170,8 +235,14 @@ def cohere_uc_capital(frame: Frame) -> UKUCCapitalCoherenceResult: return UKUCCapitalCoherenceResult( frame=result_frame, post_fill_reporter_count=int(reporter.sum()), - redrawn_spi_reporter_count=int(redraw.sum()), + redrawn_spi_reporter_count=int((redraw & reporter).sum()), refreshed_would_claim_count=int((~previous_would_claim & reporter).sum()), + redrawn_spi_benefit_units=int(redraw.sum()), + coarsening_levels=levels, + capital_against_investment_income={ + "before": receipt_before, + "after": receipt_after, + }, ) @@ -185,50 +256,102 @@ def _post_fill_reporter_anchor( return benunit["benunit_id"].isin(reporter_ids).to_numpy(dtype=bool) -def _redraw_spi_reporter_capital( +def _redraw_spi_capital( benunit: pd.DataFrame, *, person: pd.DataFrame, - household: pd.DataFrame, - household_weights: np.ndarray, + weights: np.ndarray, reporter: np.ndarray, base: np.ndarray, redraw: np.ndarray, capital: np.ndarray, -) -> None: - weights = _household_to_benunit_weights( - benunit, - person=person, - household=household, - household_weights=household_weights, - ) + investment: np.ndarray, + minimum_cell_donors: int = UC_CAPITAL_MINIMUM_CELL_DONORS, +) -> dict[str, int]: + """Redraw ``redraw`` units' capital from base donors in their cell. + + A cell is reporter status x investment-income band x couple x + dependent-children band. A cell with fewer than ``minimum_cell_donors`` + donors widens in the declared ``UC_CAPITAL_COARSENING`` order; reporter + status is never coarsened, and an empty reporter-status pool refuses. + Returns the number of redrawn units drawn at each level. + """ + + if not isinstance(minimum_cell_donors, int) or minimum_cell_donors <= 0: + raise ValueError("minimum_cell_donors must be a positive integer.") child_band = _dependent_children_band(benunit["dependent_children"]) couple = frs_uc_couple_mask(person, benunit) + income_band = _investment_income_band(investment) + last_band = len(UC_CAPITAL_INCOME_BAND_EDGES) # Domain-validated upstream: every non-sentinel value is >= 0. - available = capital >= 0.0 - donor = base & reporter & available & (weights > 0.0) + donor = base & (capital >= 0.0) & (weights > 0.0) target_ids = benunit["benunit_id"].to_numpy() draws = stable_identity_uniforms( target_ids, seed=UC_CAPITAL_REDRAW_SEED, salt=UC_CAPITAL_REDRAW_SALT, ) - - for band, is_couple in sorted( - set(zip(child_band[redraw], couple[redraw], strict=True)) - ): - target_cell = redraw & (child_band == band) & (couple == is_couple) - donor_cell = donor & (child_band == band) & (couple == is_couple) + source_capital = capital.copy() + levels = dict.fromkeys(_UC_CAPITAL_LEVELS, 0) + cells = sorted( + set( + zip( + reporter[redraw], + income_band[redraw], + couple[redraw], + child_band[redraw], + strict=True, + ) + ) + ) + for is_reporter, band, is_couple, children in cells: + target_cell = ( + redraw + & (reporter == is_reporter) + & (income_band == band) + & (couple == is_couple) + & (child_band == children) + ) + same_status = donor & (reporter == is_reporter) + candidates = [ + ( + "exact_cell", + same_status + & (income_band == band) + & (couple == is_couple) + & (child_band == children), + ), + ( + UC_CAPITAL_COARSENING[0], + same_status & (income_band == band) & (couple == is_couple), + ), + (UC_CAPITAL_COARSENING[1], same_status & (income_band == band)), + *( + ( + UC_CAPITAL_COARSENING[2], + same_status & (np.abs(income_band - band) <= width), + ) + for width in range(1, last_band + 1) + ), + (UC_CAPITAL_COARSENING[3], same_status), + ] + level, donor_cell = next( + ( + (name, pool) + for name, pool in candidates + if int(pool.sum()) >= minimum_cell_donors + ), + candidates[-1], + ) if not donor_cell.any(): - label = "3+" if band == 3 else str(band) raise ValueError( - "UC capital redraw has no positive-weight base-FRS reporter " - f"donors for dependent_children={label}, couple={is_couple}." + "UC capital redraw has no positive-weight base-FRS donors with " + f"available capital for UC reporter status {bool(is_reporter)}." ) donor_rows = pd.DataFrame( { "benunit_id": target_ids[donor_cell], - "capital": capital[donor_cell], + "capital": source_capital[donor_cell], "weight": weights[donor_cell], } ).sort_values(["capital", "benunit_id"], kind="mergesort") @@ -237,6 +360,48 @@ def _redraw_spi_reporter_capital( cdf = np.cumsum(donor_weights) / float(donor_weights.sum()) selected = np.searchsorted(cdf, draws[target_cell], side="right") capital[target_cell] = donor_values[np.minimum(selected, len(cdf) - 1)] + levels[level] += int(target_cell.sum()) + return levels + + +def _investment_income_band(investment: np.ndarray) -> np.ndarray: + """Band 0 for no investment income, then one band per declared edge.""" + + values = np.asarray(investment, dtype=float) + if not np.isfinite(values).all() or (values < 0.0).any(): + raise ValueError("investment income must be finite and nonnegative.") + return np.searchsorted( + np.asarray(UC_CAPITAL_INCOME_BAND_EDGES), values, side="left" + ).astype(np.int8) + + +def _capital_against_investment_income( + capital: np.ndarray, + investment: np.ndarray, + weights: np.ndarray, + *, + base: np.ndarray, + spi: np.ndarray, + reporter: np.ndarray, +) -> dict[str, object]: + """Units whose investment income implies capital above a UC limit they lack.""" + + implied = np.asarray(investment, dtype=float) / UC_CAPITAL_IMPLIED_YIELD + receipt: dict[str, object] = {} + for limit in _UC_CAPITAL_RECEIPT_LIMITS: + incoherent = (implied > limit) & (capital <= limit) + receipt[f"implied_above_{int(limit)}_capital_at_or_below"] = { + name: { + "benefit_units": int((rows & incoherent).sum()), + "weighted_benefit_units": float(weights[rows & incoherent].sum()), + } + for name, rows in (("frs", base), ("spi", spi)) + } + upper = _UC_CAPITAL_RECEIPT_LIMITS[-1] + receipt[f"spi_reporters_capital_above_{int(upper)}"] = int( + (spi & reporter & (capital > upper)).sum() + ) + return receipt def _household_to_benunit_weights( @@ -305,15 +470,23 @@ def _assert_stage_parameters(stage: SourceStageSpec) -> None: parameters = redraw[0].parameters expected = { "output": UC_CAPITAL_REDRAW_OUTPUT, + "rows": UC_CAPITAL_REDRAW_ROWS, + "donor_rows": UC_CAPITAL_REDRAW_DONOR_ROWS, + "reporter_status": UC_CAPITAL_REPORTER_STATUS, + "investment_income": UC_CAPITAL_INVESTMENT_INCOME, + "investment_income_band_edges": list(UC_CAPITAL_INCOME_BAND_EDGES), + "minimum_cell_donors": UC_CAPITAL_MINIMUM_CELL_DONORS, + "coarsening": list(UC_CAPITAL_COARSENING), "seed": UC_CAPITAL_REDRAW_SEED, "salt": UC_CAPITAL_REDRAW_SALT, "couple_status": "is_uc_couple", } actual = {key: parameters.get(key) for key in expected} if actual != expected: + drifted = sorted(key for key in expected if actual[key] != expected[key]) raise ValueError( - "uc_capital_coherence redraw parameters drifted: " - f"expected {expected}, got {actual}." + "uc_capital_coherence redraw parameters drifted on " + f"{drifted}: expected {expected}, got {actual}." ) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_relationships.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_relationships.py index 7e39c875a..16ce77e1f 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_relationships.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/uc_relationships.py @@ -81,3 +81,90 @@ def frs_uc_couple_mask(person: pd.DataFrame, benunit: pd.DataFrame) -> np.ndarra .reindex(benunit["benunit_id"]) ) return counts.eq(2).to_numpy(dtype=bool) + + +#: Benefit-unit financial investment income: interest (tax-free included), +#: dividends and other investment income. TOTCAPB4 counts accounts and assets +#: and has no property code (SN 9563), so let-property income is not part of +#: the capital it predicts (microcosm#1095). +UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS = ( + "savings_interest_income", + "dividend_income", + "other_investment_income", +) + + +def benunit_financial_investment_income( + person: pd.DataFrame, benunit: pd.DataFrame +) -> np.ndarray: + """Sum each member's financial investment income in benefit-unit row order.""" + + missing = sorted( + {"person_benunit_id", *UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS} - set(person) + ) + if missing: + raise KeyError(f"benefit-unit investment income inputs missing: {missing}") + values = ( + person[list(UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS)] + .apply(pd.to_numeric, errors="coerce") + .sum(axis=1, min_count=len(UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS)) + ) + if not np.isfinite(values.to_numpy(dtype=float, na_value=np.nan)).all(): + raise ValueError("benefit-unit investment income inputs must be finite.") + if (values < 0.0).any(): + raise ValueError("benefit-unit investment income inputs must be nonnegative.") + totals = values.groupby(person["person_benunit_id"].to_numpy(), sort=False).sum() + return ( + totals.reindex(benunit["benunit_id"].to_numpy()) + .fillna(0.0) + .to_numpy(dtype=float) + ) + + +def household_family_role_counts( + person: pd.DataFrame, household: pd.DataFrame +) -> tuple[np.ndarray, np.ndarray]: + """Claimants and partners, and every other member, per household. + + In household row order. The persisted FRS adult-file role + ``is_uc_claimant`` splits each household into its adults and its dependent + children the way survey household grids do (WAS ``NumAdultR8`` and + ``NumChildR8`` sum to the household size), rather than at the engine's + age-18 ``is_adult`` (uk-data#486, microcosm#1095). + """ + + missing = sorted({"person_household_id", "is_uc_claimant"} - set(person)) + if missing: + raise KeyError(f"household role-count inputs missing: {missing}") + role = person["is_uc_claimant"] + if not pd.api.types.is_bool_dtype(role.dtype): + raise ValueError("is_uc_claimant must be a boolean column.") + claimant = role.to_numpy(dtype=bool) + members = person["person_household_id"].to_numpy() + ids = household["household_id"].to_numpy() + adults = ( + pd.Series(claimant.astype(float)).groupby(members, sort=False).sum() + ).reindex(ids, fill_value=0.0) + children = ( + pd.Series((~claimant).astype(float)).groupby(members, sort=False).sum() + ).reindex(ids, fill_value=0.0) + return adults.to_numpy(dtype=float), children.to_numpy(dtype=float) + + +def uc_family_child_member( + claimant: np.ndarray, qualifying: np.ndarray, age: np.ndarray +) -> np.ndarray: + """Members DWP's Universal Credit family-type counts treat as children. + + Never a claimant or partner (``claimant``, the FRS adult-file role); any + UC child or qualifying young person (``qualifying``), or any other member + under 20, since DWP's post-April-2019 child-presence definition includes + reported under-20 children beyond those eligible for a child element: + https://stat-xplore.dwp.gov.uk/webapi/metadata/UC_Households/Family%20Type.html + One rule for the national family-type composition and the constituency + child bands (uk-data#486, microcosm#1095). + """ + + return ~np.asarray(claimant, dtype=bool) & ( + np.asarray(qualifying, dtype=bool) | (np.asarray(age, dtype=float) < 20) + ) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/was_wealth.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/was_wealth.py index eb0980c3d..7fe9dbf68 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/was_wealth.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/was_wealth.py @@ -36,6 +36,9 @@ UK_TENURE_SOCIAL_RENT, UK_TENURE_TYPE_TO_CATEGORY, ) +from microcosm.build.uk_runtime.uc_relationships import ( + household_family_role_counts, +) from microcosm.frame import Frame from microcosm.frame.rules import assert_rules_engine_country @@ -61,15 +64,20 @@ "employment_income", "self_employment_income", "capital_income", + # Net rental income: WAS investment income excludes rent, so without it + # the property draws have no income of their own (uk-data#495, + # microcosm#1095). + "rental_income", "num_bedrooms", "council_tax", *UK_WAS_TENURE_PREDICTORS, "region", ) +#: The household counts come from the FRS family roles instead +#: (``uc_relationships.household_family_role_counts``), matching the donor's +#: NumAdultR8 and NumChildR8. UK_WAS_ENGINE_PREDICTORS = ( "household_net_income", - "num_adults", - "num_children", "private_pension_income", "employment_income", "self_employment_income", @@ -184,8 +192,6 @@ REGION_REMAP = {"NORTHERN_IRELAND": "WALES"} UK_WAS_ENGINE_PREDICTOR_ENTITIES: Mapping[str, str] = { "household_net_income": "household", - "num_adults": "benunit", - "num_children": "benunit", "private_pension_income": "person", "employment_income": "person", "self_employment_income": "person", @@ -236,7 +242,10 @@ "totalpenr8_aggr": "pensions", "dvvaldbt_scaper8_aggr": "db_pensions", "NumAdultR8": "num_adults", - "NumCh18R8": "num_children", + # NumChildR8 + NumAdultR8 is the household size on 99.99% of rows; the + # under-18 NumCh18R8 also counts the 16- and 17-year-olds NumAdultR8 + # counts, overrunning the size on 5.6% of rows (uk-data#486). + "NumChildR8": "num_children", "DVGIPPENR8_AGGR": "private_pension_income", "DVGISER8_AGGR": "self_employment_income", "DVGIINVR8_aggr": "capital_income", @@ -244,7 +253,10 @@ "HBedRmR8": "num_bedrooms", "GORR8": "region_code", "DVPriRntR8": "private_rent_code", - "CTAmtR8": "council_tax", + # The annual council tax paid; CTAmtR8 is one instalment (weighted mean + # GBP 479 against 1,395 on the pinned tab; microcosm#1095). + "DVCTaxAmtAnnualR8": "council_tax", + "DVNetRentAmtAnnualR8_aggr": "rental_income", "HFINWNTR8_Sum": "net_financial_wealth", # WAS round-8 household derived variables (UKDS SN 7215, DOI # 10.5255/UKDA-SN-7215-20; round-8 user guide and derived-variable @@ -267,7 +279,11 @@ "OthMortR8_sum": "other_property_mortgage", "Ten1R8": "tenure_code", "DVhvalueR8": "main_residence_value", - "DVHseValR8_sum": "other_residential_property_value", + # Houses other than the main residence and buy-to-let property together + # are the engine's other residential property; the buy-to-let value sat + # in the undrawn other-property remainder (uk-data#501, microcosm#1095). + "DVHseValR8_sum": "other_houses_value", + "DVBltValR8_sum": "buy_to_let_property_value", "DVBlDValR8_sum": "non_residential_property_value", "DVTotinc_bhcR8": "household_net_income", "DVSaValR8_aggr": "savings", @@ -433,9 +449,17 @@ def clean_was_household_table(raw: pd.DataFrame) -> pd.DataFrame: for column in cleaned.columns: cleaned[column] = pd.to_numeric(cleaned[column], errors="coerce") cleaned = cleaned.fillna(0) + if (cleaned["rental_income"] < 0.0).any(): + raise ValueError( + "WAS donor DVNetRentAmtAnnualR8_aggr carries negative values; the " + "rent predictor has no reviewed reading for a sentinel or a loss." + ) for column in _SENTINEL_RECODE_COLUMNS: values = cleaned[column] cleaned[column] = values.where(~values.isin(_SENTINEL_CODES), 0) + cleaned["other_residential_property_value"] = ( + cleaned["other_houses_value"] + cleaned["buy_to_let_property_value"] + ) # Private renting households, the flag the Lifetime ISA stage reads on # both sides (``was_lisa``); this stage's own tenure predictors are the # four-way flags below. @@ -629,10 +653,32 @@ def recipient_predictors(frame: Frame, engine: object) -> pd.DataFrame: .sum() ) result[predictor] = summed.reindex(household_ids).fillna(0.0).to_numpy() + adults, children = household_family_role_counts(person, household) + result["num_adults"] = adults + result["num_children"] = children + if "property_income" not in person.columns: + raise KeyError("recipient person table is missing 'property_income'.") + rent = ( + pd.to_numeric(person["property_income"], errors="coerce") + .fillna(0.0) + .groupby(person["person_household_id"].to_numpy()) + .sum() + ) + result["rental_income"] = rent.reindex(household_ids).fillna(0.0).to_numpy() for predictor in ("num_bedrooms", "council_tax", "region"): if predictor not in household.columns: raise KeyError(f"recipient household table is missing {predictor!r}.") result[predictor] = household[predictor].to_numpy() + # The donor records the bill the household pays and the spine's + # council_tax is the liability before council tax reduction, so the + # predictor is the paid bill (uk-data#496/#499, microcosm#1095). + if "council_tax_rebate" not in household.columns: + raise KeyError("recipient household table is missing 'council_tax_rebate'.") + result["council_tax"] = np.maximum( + household["council_tax"].to_numpy(dtype=float) + - household["council_tax_rebate"].to_numpy(dtype=float), + 0.0, + ) result["region"] = result["region"].map(_enum_name).replace(REGION_REMAP) if "tenure_type" not in household.columns: raise KeyError("recipient household table is missing 'tenure_type'.") @@ -1341,6 +1387,23 @@ def _assert_chain_declaration(stage: SourceStageSpec) -> None: "was_wealth stratified_targets drifted: manifest declares " f"{declared_strata!r}, runtime uses {dict(UK_WAS_STRATIFIED_TARGETS)!r}." ) + declared_predictors = tuple(operation.parameters.get("predictors", ())) + if declared_predictors != UK_WAS_WEALTH_PREDICTORS: + raise ValueError( + "was_wealth predictors drifted: manifest declares " + f"{declared_predictors!r}, runtime uses {UK_WAS_WEALTH_PREDICTORS!r}." + ) + materialized = next( + op + for op in stage.operations + if op.kind == "materialize_rules_engine_predictors" + ) + declared_engine = tuple(materialized.parameters.get("predictors", ())) + if declared_engine != UK_WAS_ENGINE_PREDICTORS: + raise ValueError( + "was_wealth engine predictors drifted: manifest declares " + f"{declared_engine!r}, runtime materializes {UK_WAS_ENGINE_PREDICTORS!r}." + ) declared_totals = { str(total): tuple(components) for total, components in dict( diff --git a/packages/microcosm-build/tests/engine/uk/test_uk_spi_income.py b/packages/microcosm-build/tests/engine/uk/test_uk_spi_income.py index a19babdfd..33d31fe46 100644 --- a/packages/microcosm-build/tests/engine/uk/test_uk_spi_income.py +++ b/packages/microcosm-build/tests/engine/uk/test_uk_spi_income.py @@ -63,12 +63,7 @@ def test_spi_rebases_income_before_frs_fill_and_preserves_child_inputs( lambda year: (factors, {"from_period": 2022, "to_period": year}), raising=False, ) - options = dict( - seed=9, - n_estimators=3, - donor_sample_size=None, - stage1_base_redraw_columns=("dividend_income",), - ) + options = dict(seed=9, n_estimators=3, donor_sample_size=None) reference = impute_uk_spi_income_support(support, donor_path, **options) result = impute_uk_spi_income_support( support, @@ -85,21 +80,27 @@ def test_spi_rebases_income_before_frs_fill_and_preserves_child_inputs( # Only taxable SPI interest is rebased; the FRS fill's £5 tax-free draw # is already in the build-year basis and must not be doubled. assert result.person.loc[spi, "savings_interest_income"].eq(205).all() - assert ( - result.person.loc[base_child, "dividend_income"] - == person.loc[base_child, "dividend_income"] - ) - base_adult = person[channel].eq("frs") & person.age.ge(16) + # FRS rows keep their own reported dividends, children and adults alike: + # the SPI forest never redraws them (uk-data#498, microcosm#1095). + base = person[channel].eq("frs") np.testing.assert_array_equal( - result.person.loc[base_adult, "dividend_income"], - 2 * reference.person.loc[base_adult, "dividend_income"], + result.person.loc[base, "dividend_income"], + person.loc[base, "dividend_income"], ) assert result.income_uprating == {"from_period": 2022, "to_period": 2024} -def test_child_exclusion_keeps_the_base_dividend_random_stream( +def test_child_exclusion_keeps_the_other_recipients_draws( monkeypatch, tmp_path ) -> None: + """Dropping a recipient leaves every other SPI row's stage-1 draw unchanged. + + The forest is queried with the legacy shape (every SPI-channel person) and + the rows outside the recipient domain are discarded afterwards, so the + draw stream each recipient consumes does not depend on who else is in it. + FRS rows are never redrawn. + """ + support = _dead_support() donor_path = tmp_path / SPI_DONOR_FILENAME _write_donor(donor_path) @@ -116,27 +117,110 @@ def predict(self, predictors): monkeypatch.setattr(_FakeFittedQRF, "predict", predict) monkeypatch.setattr(spi_income, "QRF", _FakeQRF) _bypass_reviewed_donor_identity(monkeypatch) - options = dict( - seed=9, - n_estimators=3, - donor_sample_size=None, - stage1_base_redraw_columns=("dividend_income",), - ) + options = dict(seed=9, n_estimators=3, donor_sample_size=None) reference = impute_uk_spi_income_support(support, donor_path, **options) person = support.person.copy() channel = support_channel_column("person") - child = person.index[person[channel].eq("spi")][0] + spi_rows = person.index[person[channel].eq("spi")] + child = spi_rows[0] person.loc[child, "age"] = 15 candidate = impute_uk_spi_income_support( replace(support, person=person), donor_path, **options ) + others = spi_rows.drop(child) + np.testing.assert_array_equal( + reference.person.loc[others, "dividend_income"], + candidate.person.loc[others, "dividend_income"], + ) base = person[channel].eq("frs") np.testing.assert_array_equal( - reference.person.loc[base, "dividend_income"], candidate.person.loc[base, "dividend_income"], + support.person.loc[base, "dividend_income"], ) +def test_dependants_keep_their_twin_values_and_recipients_their_draws( + monkeypatch, tmp_path +) -> None: + """A dependant aged 16 to 19 is not a taxpayer the tape samples. + + Neither forest draws for it, so it keeps every value of its FRS twin, and + both forests are still queried over the age domain, so every other + recipient keeps the stage-1 and stage-2 draws it had (uk-data#504, + microcosm#1095). + """ + + support = _dead_support() + donor_path = tmp_path / SPI_DONOR_FILENAME + _write_donor(donor_path) + original_predict = _FakeFittedQRF.predict + + def predict(self, predictors): + result = original_predict(self, predictors) + for target in ("dividend_income", "universal_credit_reported"): + if target in result: + consumed = getattr(self, "consumed", 0) + result[target] = consumed + np.arange(len(result), dtype=float) + self.consumed = consumed + len(result) + return result + + monkeypatch.setattr(_FakeFittedQRF, "predict", predict) + monkeypatch.setattr(spi_income, "QRF", _FakeQRF) + _bypass_reviewed_donor_identity(monkeypatch) + options = dict(seed=9, n_estimators=3, donor_sample_size=None) + reference = impute_uk_spi_income_support(support, donor_path, **options) + person = support.person.copy() + channel = support_channel_column("person") + spi_rows = person.index[person[channel].eq("spi")] + dependant = spi_rows[0] + person.loc[dependant, "age"] = 17 + person.loc[dependant, "is_uc_claimant"] = False + candidate = impute_uk_spi_income_support( + replace(support, person=person), donor_path, **options + ) + + others = spi_rows.drop(dependant) + for column in ("dividend_income", "universal_credit_reported"): + np.testing.assert_array_equal( + reference.person.loc[others, column], candidate.person.loc[others, column] + ) + twin_columns = [ + column + for column in ( + *SPI_INCOME_QRF_OUTPUT_COLUMNS, + *FRS_ONLY_SPI_FILL_PERSON_COLUMNS, + "employment_income", + ) + if column in person.columns + ] + assert twin_columns + pd.testing.assert_series_equal( + candidate.person.loc[dependant, twin_columns], + person.loc[dependant, twin_columns], + check_names=False, + ) + assert candidate.person.loc[dependant, HMRC_SPI_ASSESSABLE_INCOME_COLUMN] == 0.0 + assert candidate.recipient_domain["dependant_rows_kept_on_twin_values"] == 1 + assert candidate.spi_prediction_rows == reference.spi_prediction_rows - 1 + + +def test_spi_income_refuses_a_frame_without_the_claimant_role( + monkeypatch, tmp_path +) -> None: + support = _dead_support() + donor_path = tmp_path / SPI_DONOR_FILENAME + _write_donor(donor_path) + monkeypatch.setattr(spi_income, "QRF", _FakeQRF) + _bypass_reviewed_donor_identity(monkeypatch) + options = dict(seed=9, n_estimators=3, donor_sample_size=None) + missing = replace(support, person=support.person.drop(columns="is_uc_claimant")) + with pytest.raises(ValueError, match="is_uc_claimant"): + impute_uk_spi_income_support(missing, donor_path, **options) + coded = replace(support, person=support.person.assign(is_uc_claimant=1.0)) + with pytest.raises(ValueError, match="must be boolean"): + impute_uk_spi_income_support(coded, donor_path, **options) + + def test_stage2_pension_bridge_uses_observed_and_drawn_receipt( monkeypatch, tmp_path ) -> None: @@ -430,7 +514,7 @@ def test_the_spi_channel_ships_no_structural_nan_on_the_frs_channel( @pytest.mark.parametrize("age", [15, 16]) @pytest.mark.parametrize("channel", ["frs", "spi"]) -def test_spi_donor_age_boundary_applies_to_both_recipient_channels( +def test_spi_donor_age_boundary_and_frs_rows_keep_their_reports( monkeypatch, tmp_path, age, channel ) -> None: support = _dead_support() @@ -451,18 +535,14 @@ def test_spi_donor_age_boundary_applies_to_both_recipient_channels( seed=9, n_estimators=3, donor_sample_size=None, - stage1_base_redraw_columns=("dividend_income",), ) - if age == 15: + if age == 15 or channel == "frs": assert result.person.loc[recipient, "dividend_income"] == 987.0 assert result.person.loc[recipient, "universal_credit_reported"] == 1234.0 else: assert result.person.loc[recipient, "dividend_income"] == 3.0 - if channel == "spi": - assert result.person.loc[recipient, "universal_credit_reported"] != 1234.0 - else: - assert result.person.loc[recipient, "universal_credit_reported"] == 1234.0 + assert result.person.loc[recipient, "universal_credit_reported"] != 1234.0 def test_spi_uprating_uses_actual_engine_indices_and_explicit_nominal_holdouts() -> ( diff --git a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py index c1b42f6b4..d0206f004 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py @@ -1015,7 +1015,7 @@ def test_uk_source_manifest_contains_only_canonical_spine_stages(self) -> None: # newest); the frs_hmrc_retained_leaves / hmrc_spi_income pair is # retired (#901). # microcosm#1063 also adds cgt_residential_split after the anchor. - assert len(spec.sources.stages) == 38 + assert len(spec.sources.stages) == 39 assert not {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.intersection( stage.stage for stage in spec.sources.stages ) @@ -1398,6 +1398,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", + "uk_stage_spi_benefit_coherence", "uk_stage_pension_credit_take_up", "uk_stage_child_benefit_take_up", "uk_stage_cgt_incidence_clone_mass", @@ -1504,6 +1505,7 @@ def test_strict_absent_evidence_entries_are_declared(self, manifest) -> None: "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", + "uk_stage_spi_benefit_coherence", "uk_stage_pension_credit_take_up", "uk_stage_child_benefit_take_up", "uk_stage_cgt_incidence_clone_mass", diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_benefit_target_scope.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_benefit_target_scope.py new file mode 100644 index 000000000..57acf809c --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_benefit_target_scope.py @@ -0,0 +1,188 @@ +"""Country scope of the benefit rows bound against DWP's lines (microcosm#1095, uk-data#490). + +OBR table 4.9 reports "DWP social security" lines, whose figures cover Great Britain (DWP benefit +expenditure and caseload tables, Spring 2026, Notes 3), with Northern Ireland social security on +rows of its own. DWP reports Attendance Allowance, Carer's Allowance, DLA/PIP and Winter Fuel +Payment for England and Wales only since executive competence moved to the Scottish Government. +Each row binds the model column over the same households the publisher counts. +""" + +from __future__ import annotations + +import json +from pathlib import Path + +import microcosm.build +from microcosm.build.uk_runtime.local_targets import load_uk_population_contract + +GB_REGIONS = { + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "WALES", + "SCOTLAND", +} +GB_COUNTRIES = {"ENGLAND", "WALES", "SCOTLAND"} +GREAT_BRITAIN_CODE = "K03000001" +GREAT_BRITAIN_ROWS = ( + "obr.pension_credit", + "obr.esa", + "obr.jobseekers_allowance", + "obr.universal_credit", + "obr.universal_credit_in_cap", + "obr.universal_credit_outside_cap", + "obr.housing_benefit", + "obr.statutory_maternity_pay", + "dwp.esa_claimants", + "dwp.esa_contrib_claimants", + "dwp.esa_income_claimants", + "dwp.jsa_claimants", +) +ENGLAND_AND_WALES_ROWS = ( + "obr.attendance_allowance", + "obr.carers_allowance", + "obr.pip", + "obr.winter_fuel_allowance", +) +# OBR table 4.9 concepts reported inside "DWP social security". +DWP_SOCIAL_SECURITY_CONCEPTS = { + "obr.attendance_allowance", + "obr.carers_allowance", + "obr.dla_and_pip", + "obr.housing_benefit", + "obr.incapacity_benefits", + "obr.jobseekers_allowance", + "obr.pension_credit", + "obr.statutory_maternity_pay", + "obr.universal_credit_in_cap", + "obr.universal_credit_outside_cap", + "obr.winter_fuel_payment", + "obr.state_pension", +} + + +def _targets() -> dict[str, dict]: + return { + target["target_id"]: target + for target in load_uk_population_contract()["targets"] + } + + +def _concepts(target: dict) -> set[str]: + concept = target.get("ledger_selector", {}).get("source_concept") + if concept is None: + return set() + return {concept} if isinstance(concept, str) else set(concept) + + +def _country_filter(target: dict) -> dict: + filters = [ + predicate + for predicate in target["measurement"].get("filters", ()) + if predicate.get("concept") == "uk.geography.country" + ] + assert len(filters) == 1, target["target_id"] + return filters[0] + + +def _condition(target: dict) -> dict: + binding = target["bindings"]["policyengine"] + conditions = binding.get("household_conditions", ()) + assert len(conditions) == 1, target["target_id"] + condition = conditions[0] + assert condition["entity"] == "household", target["target_id"] + assert condition["reduce"] == "any", target["target_id"] + assert condition["operator"] == "in", target["target_id"] + assert condition["map_to"] == binding.get("from_entity", "household") + return condition + + +def test_dwp_social_security_rows_bind_great_britain_households() -> None: + targets = _targets() + for target_id in GREAT_BRITAIN_ROWS: + target = targets[target_id] + condition = _condition(target) + assert condition["variable"] == "region", target_id + assert set(condition["value"]) == GB_REGIONS, target_id + assert len(condition["value"]) == len(GB_REGIONS), target_id + assert set(_country_filter(target)["value"]) == { + "england", + "scotland", + "wales", + }, target_id + + +def test_devolved_benefit_rows_bind_england_and_wales_households() -> None: + targets = _targets() + for target_id in ENGLAND_AND_WALES_ROWS: + target = targets[target_id] + condition = _condition(target) + assert condition["variable"] == "country", target_id + assert condition["value"] == ["ENGLAND", "WALES"], target_id + assert set(_country_filter(target)["value"]) == {"england", "wales"}, target_id + + +def test_every_dwp_social_security_row_is_scoped() -> None: + """A row added against a DWP line cannot bind the UK column by default.""" + + scoped = set(GREAT_BRITAIN_ROWS) | set(ENGLAND_AND_WALES_ROWS) + for target_id, target in _targets().items(): + if _concepts(target) & DWP_SOCIAL_SECURITY_CONCEPTS: + assert target_id in scoped, target_id + assert target["bindings"]["policyengine"].get("household_conditions"), ( + target_id + ) + + +def _scoped_to_great_britain(binding: dict) -> bool: + for predicate in ( + *binding.get("household_conditions", ()), + *binding.get("filters", ()), + ): + variable = predicate.get("variable") + operator = predicate.get("operator") + value = predicate.get("value") + values = set(value) if isinstance(value, list) else {value} + allowed = {"region": GB_REGIONS, "country": GB_COUNTRIES}.get(variable) + if allowed is None or not values: + continue + if operator in ("in", "==") and values <= allowed: + return True + if operator in ("!=", "not_in") and "NORTHERN_IRELAND" in values: + return True + return False + + +def test_every_active_great_britain_fact_binds_great_britain_households() -> None: + """A row whose fact is pinned to Great Britain never measures the UK column.""" + + membership = json.loads( + ( + Path(microcosm.build.__file__).parent + / "uk" + / "target_reference_membership.json" + ).read_text() + ) + targets = _targets() + unscoped = sorted( + target_id + for target_id, pin in membership["geography_pins"].items() + if pin.get("geography_id") == GREAT_BRITAIN_CODE + and membership["targets"].get(target_id, {}).get("status") == "active" + and not _scoped_to_great_britain(targets[target_id]["bindings"]["policyengine"]) + ) + assert unscoped == [] + + +def test_obr_pip_binds_dla_and_pip_together() -> None: + """OBR's line is "Disability living allowance and personal independence payments".""" + + binding = _targets()["obr.pip"]["bindings"]["policyengine"] + assert binding["value_expression"] == "pip + dla" + assert "value_variable" not in binding diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_services.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_services.py index ec58c4d88..6e1297bb5 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_services.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_services.py @@ -288,6 +288,7 @@ def materialize(self, frame, variables, period): "person_id": [1, 2, 3, 4], "person_household_id": [10, 10, 10, 20], "person_benunit_id": [100, 100, 100, 200], + "is_uc_claimant": [True, True, False, True], } ) benunit = pd.DataFrame({"benunit_id": [100, 200], "benunit_household_id": [10, 20]}) @@ -301,6 +302,9 @@ def materialize(self, frame, variables, period): result = recipient_predictors(frame, _FakeEngine()) + # The adult and child counts are the FRS family roles (microcosm#1095). + assert result["is_adult"].tolist() == [2.0, 1.0] + assert result["is_child"].tolist() == [1.0, 0.0] assert result["count_primary_education"].tolist() == [1.0, 0.0] assert result["count_secondary_education"].tolist() == [0.0, 1.0] assert result["count_further_education"].tolist() == [1.0, 0.0] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_vat.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_vat.py index 0a886d1b2..444150ec7 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_vat.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_etb_vat.py @@ -136,9 +136,11 @@ def fit(self, donor, predictors, targets, *, weights): def test_recipient_predictors_aggregate_person_entities_to_household() -> None: - # Regression for the licensed-build crash: is_adult / is_child / is_SP_age - # materialize at person grain and must aggregate to household — direct - # engine arrays fail on the person/household length mismatch. + # Regression for the licensed-build crash: is_SP_age materializes at person + # grain and must aggregate to household — direct engine arrays fail on + # the person/household length mismatch. The adult and child counts are the + # FRS family roles (microcosm#1095): person 2 is an 18-year-old dependent + # child, an adult to the engine and a child to the donor's ``childs``. from types import SimpleNamespace from microcosm.build.uk_runtime.etb_vat import recipient_predictors @@ -171,6 +173,7 @@ def materialize(self, frame, variables, period): "person_id": [1, 2, 3, 4], "person_household_id": [10, 10, 10, 20], "person_benunit_id": [100, 100, 100, 200], + "is_uc_claimant": [True, False, False, True], } ) benunit = pd.DataFrame({"benunit_id": [100, 200], "benunit_household_id": [10, 20]}) @@ -184,8 +187,8 @@ def materialize(self, frame, variables, period): result = recipient_predictors(frame, _FakeEngine()) - assert result["is_adult"].tolist() == [2.0, 1.0] - assert result["is_child"].tolist() == [1.0, 0.0] + assert result["is_adult"].tolist() == [1.0, 1.0] + assert result["is_child"].tolist() == [2.0, 0.0] assert result["is_SP_age"].tolist() == [1.0, 0.0] assert result["household_net_income"].tolist() == [1e4, 2e4] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_council_tax.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_council_tax.py index 4e7b76897..4e5ac7e66 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_council_tax.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_council_tax.py @@ -1,36 +1,200 @@ from __future__ import annotations +import json + import numpy as np import pandas as pd +import pytest -from microcosm.build.uk_runtime.frs_council_tax import derive_council_tax +from microcosm.build.source_manifest import SourceManifest, SourceStageSpec +from microcosm.build.uk_runtime.frs_council_tax import ( + SCOTTISH_CHARGES_IN_RECIPIENT_BILL, + assert_frs_council_tax_stage_parameters, + derive_council_tax, +) from microcosm.build.uk_runtime.frs_spine import WEEKS_IN_YEAR +from test_support.paths import paths_for + +UK_PACKAGE = ( + paths_for("microcosm-build").repository + / "packages/microcosm-build/src/microcosm/build/uk" +) + + +def _raw(**columns) -> pd.DataFrame: + rows = len(columns["ctannual"]) + defaults = { + "household_id": list(range(1, rows + 1)), + "ctreb": [2] * rows, + "ctrebamt": [0.0] * rows, + "gvtregno": [1] * rows, + "ctband": [4] * rows, + "adulth": [2] * rows, + "cwatamt1": [0.0] * rows, + "csewamt1": [0.0] * rows, + "cwatamtd": [0.0] * rows, + } + return pd.DataFrame({**defaults, **columns}) + + +def _derive(raw: pd.DataFrame) -> pd.Series: + return derive_council_tax(pd.DataFrame({"household_id": raw["household_id"]}), raw) def test_council_tax_imputes_raw_missing_from_raw_cells() -> None: - household = pd.DataFrame({"household_id": [1, 2, 3, 4, 5, 6]}) - raw = pd.DataFrame( - { - "household_id": [1, 2, 3, 4, 5, 6], - "gvtregno": [12, 12, 1, 1, 2, 2], - "ctband": [1, 1, np.nan, np.nan, 2, 2], - "adulth": [1, 1, 1, 1, 2, 2], - "ctannual": [1000.0, -1.0, 600.0, np.nan, -1.0, 0.0], - # FRS 2024-25 shape: CSEWAMT is retired and empty; the Scottish - # charge comes from CWATAMTD plus CSEWAMT1 at the household's own - # discount factor CWATAMTD/CWATAMT1. - "csewamt": [np.nan] * 6, - "cwatamtd": [3.0, 3.0, 0.0, 0.0, 0.0, 0.0], - "cwatamt1": [4.0, 4.0, 0.0, 0.0, 0.0, 0.0], - "csewamt1": [5.0, 5.0, 0.0, 0.0, 0.0, 0.0], - } - ) - - result = derive_council_tax(household, raw) - - scottish_tax = 1000.0 - (3.0 + 5.0 * 0.75) * WEEKS_IN_YEAR + raw = _raw( + gvtregno=[12, 12, 1, 1, 2, 2], + ctband=[1, 1, np.nan, np.nan, 2, 2], + adulth=[1, 1, 1, 1, 2, 2], + ctannual=[1000.0, -1.0, 600.0, np.nan, -1.0, 0.0], + # FRS 2024-25 shape: the gross Scottish cells CWATAMT1/CSEWAMT1. + cwatamtd=[3.0, 3.0, 0.0, 0.0, 0.0, 0.0], + cwatamt1=[4.0, 4.0, 0.0, 0.0, 0.0, 0.0], + csewamt1=[5.0, 5.0, 0.0, 0.0, 0.0, 0.0], + ) + + result = _derive(raw) + + # A non-recipient's bill carries the gross charges in full. + scottish_tax = 1000.0 - (4.0 + 5.0) * WEEKS_IN_YEAR assert np.isclose(result.loc[1], scottish_tax) assert np.isclose(result.loc[2], scottish_tax) assert result.loc[4] == 600.0 + # No positive non-recipient bill in the cell: nothing to impute from. assert result.loc[5] == 0.0 + # A non-recipient's zero bill (an exempt dwelling) stays zero. assert result.loc[6] == 0.0 + + +def test_reported_reduction_is_added_back_to_the_bill() -> None: + raw = _raw( + ctannual=[0.0, 500.0, 1300.0], + ctreb=[1, 1, 2], + ctrebamt=[20.0, 10.0, 0.0], + ) + + result = _derive(raw) + + # A full reduction leaves CTANNUAL at zero; the liability is the reduction. + assert result.loc[1] == pytest.approx(20.0 * WEEKS_IN_YEAR) + assert result.loc[2] == pytest.approx(500.0 + 10.0 * WEEKS_IN_YEAR) + assert result.loc[3] == pytest.approx(1300.0) + + +def test_unknown_reduction_takes_the_larger_of_bill_and_cell_mean() -> None: + raw = _raw( + ctannual=[1200.0, 1400.0, 300.0, 1500.0], + ctreb=[2, 2, 1, 1], + ctrebamt=[0.0, 0.0, 0.0, np.nan], + ) + + result = _derive(raw) + + assert result.loc[3] == pytest.approx(1300.0) + assert result.loc[4] == pytest.approx(1500.0) + + +def test_cell_means_pool_non_recipients_only() -> None: + raw = _raw( + ctannual=[1200.0, 100.0, np.nan], + ctreb=[2, 1, 2], + ctrebamt=[0.0, 15.0, 0.0], + ) + + result = _derive(raw) + + # The recipient's net bill (100) would pull the cell mean down. + assert result.loc[3] == pytest.approx(1200.0) + assert result.loc[2] == pytest.approx(100.0 + 15.0 * WEEKS_IN_YEAR) + + +def test_scottish_recipients_net_the_reduced_share_of_the_gross_charges() -> None: + raw = _raw( + gvtregno=[12, 12], + ctannual=[800.0, 1600.0], + ctreb=[1, 2], + ctrebamt=[5.0, 0.0], + cwatamt1=[4.0, 4.0], + csewamt1=[5.0, 5.0], + cwatamtd=[3.0, 3.0], + ) + + result = _derive(raw) + + charges = (4.0 + 5.0) * WEEKS_IN_YEAR + assert result.loc[1] == pytest.approx( + 800.0 - SCOTTISH_CHARGES_IN_RECIPIENT_BILL * charges + 5.0 * WEEKS_IN_YEAR + ) + assert result.loc[2] == pytest.approx(1600.0 - charges) + + +def test_scottish_household_without_a_gross_cell_nets_its_recorded_charge() -> None: + raw = _raw( + gvtregno=[12], + ctannual=[900.0], + cwatamtd=[3.0], + ) + + assert _derive(raw).loc[1] == pytest.approx(900.0 - 3.0 * WEEKS_IN_YEAR) + + +def test_bills_outside_scotland_keep_ctannual_or_add_the_reduction() -> None: + rng = np.random.default_rng(1095) + rows = 400 + raw = _raw( + gvtregno=rng.integers(1, 12, rows), + ctband=rng.integers(1, 9, rows), + adulth=rng.integers(1, 3, rows), + ctannual=rng.choice([0.0, 250.0, 900.0, 1800.0, 2600.0], rows), + ctreb=rng.choice([1, 2], rows), + ctrebamt=rng.choice([0.0, 4.0, 18.0, 30.0], rows), + ) + + result = _derive(raw).to_numpy() + ctannual = raw["ctannual"].to_numpy() + recipient = raw["ctreb"].to_numpy() == 1 + reduction = raw["ctrebamt"].to_numpy() * WEEKS_IN_YEAR + + assert np.isfinite(result).all() and (result >= 0).all() + np.testing.assert_allclose(result[~recipient], ctannual[~recipient]) + known = recipient & (reduction > 0) + np.testing.assert_allclose(result[known], ctannual[known] + reduction[known]) + assert (result[recipient] >= ctannual[recipient] - 1e-9).all() + + +def test_missing_raw_cells_refuse() -> None: + raw = _raw(ctannual=[100.0]).drop(columns="ctreb") + + with pytest.raises(KeyError, match="ctreb"): + _derive(raw) + + +def _committed_stage() -> SourceStageSpec: + manifest = SourceManifest.from_mapping( + json.loads((UK_PACKAGE / "source_stages.json").read_text(encoding="utf-8")) + ) + return next(stage for stage in manifest.stages if stage.stage == "frs_council_tax") + + +def test_committed_manifest_declares_the_implemented_rule() -> None: + assert_frs_council_tax_stage_parameters(_committed_stage()) + + +@pytest.mark.parametrize( + ("parameter", "value"), + [ + ("donor_filter", "raw ctannual > 0"), + ("value", "Scottish-water-netted CTANNUAL"), + ("cells", ["gvtregno", "ctband"]), + ], +) +def test_manifest_drift_from_the_implemented_rule_refuses(parameter, value) -> None: + stage = _committed_stage() + operations = [ + {"kind": operation.kind, **dict(operation.parameters)} + for operation in stage.operations + ] + operations[1][parameter] = value + drifted = SourceStageSpec.from_mapping({**stage.__dict__, "operations": operations}) + with pytest.raises(ValueError, match=parameter): + assert_frs_council_tax_stage_parameters(drifted) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py index f50bc194f..873b4d7de 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py @@ -27,6 +27,9 @@ spine_build, ) from microcosm.build.uk_runtime.content_identity import uk_frame_content_identity +from microcosm.build.uk_runtime.frs_council_tax import ( + frs_council_tax_operation_parameters, +) from microcosm.build.uk_runtime.frs_relationships import ( FRS_RELATIONSHIPS_OUTPUT_COLUMNS, frs_relationships_operation_parameters, @@ -34,9 +37,11 @@ from microcosm.build.uk_runtime.frs_spine import ( FRS_SPINE_TABLES, REGION_MAP, + SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE, UC_CAPITAL_UNAVAILABLE, WEEKS_IN_YEAR, UKFRSSpineStageTransform, + _add_benefits, build_uk_frs_spine_frame, scottish_water_and_sewerage_weekly, uk_frs_spine_seed_frame, @@ -156,6 +161,9 @@ def _fixture_tables() -> dict[str, list[dict[str, object]]]: "BEDROOM6": 3, "CTANNUAL": 1000.0, "CTBAND": 4, + "CTDISC": 2, + "CT25D50D": "", + "CTREB": 2, "CTREBAMT": 2.0, "ADULTH": 1, # CWATAMT/CSEWAMT are retired in FRS 2024-25: the headers survive but @@ -186,6 +194,9 @@ def _fixture_tables() -> dict[str, list[dict[str, object]]]: "BEDROOM6": 2, "CTANNUAL": -1.0, "CTBAND": 2, + "CTDISC": 1, + "CT25D50D": 1, + "CTREB": 1, "CTREBAMT": 1.0, "CSEWAMT": "", "CWATAMTD": 3.0, @@ -551,7 +562,10 @@ def source_stage( source_stage( "frs_council_tax", tables=("househol",), - operations=[{"kind": "read_tables"}, {"kind": "impute_cell_means"}], + operations=[ + {"kind": "read_tables"}, + frs_council_tax_operation_parameters(), + ], outputs=("council_tax",), nonnegative_outputs=("council_tax",), ), @@ -888,12 +902,6 @@ def source_stage( }, }, {"kind": "fit_weighted_qrf_stage2", "seed": 43}, - { - "kind": "redraw_columns_from_fitted_qrf", - "fit": "stage1", - "columns": ["dividend_income"], - "rows": "base_support_channel", - }, ], outputs=( "other_investment_income", @@ -1145,6 +1153,38 @@ def test_benefit_code_splits_are_ported(tmp_path: Path) -> None: assert adult["bsp_reported"] == pytest.approx(6 * WEEKS_IN_YEAR) +def test_scottish_disability_payments_land_in_the_pip_and_dla_columns() -> None: + """ADP and CDP rows map to the columns of the benefits they replace (uk-data#500). + + Adult Disability Payment (117 daily living, 118 mobility) mirrors PIP and Child + Disability Payment (121 care, 122 mobility) mirrors DLA; the benefit recovery + codes 69 and 70 are deductions and reach no reported amount. + """ + + person = pd.DataFrame({"person_id": [1001, 1002, 1003]}) + pe_person = pd.DataFrame(index=person.index) + benefits = pd.DataFrame( + { + "person_id": [1001, 1001, 1002, 1002, 1003, 1003, 1001, 1002], + "benefit": [117, 118, 121, 122, 96, 1, 69, 70], + "var2": [0] * 8, + "benamt": [110.40, 28.70, 72.65, 28.70, 73.90, 29.20, 9.0, 11.0], + } + ) + + _add_benefits(pe_person, person, benefits) + + weekly = pe_person.div(WEEKS_IN_YEAR) + assert weekly["pip_dl_reported"].tolist() == pytest.approx([110.40, 0.0, 73.90]) + assert weekly["pip_m_reported"].tolist() == pytest.approx([28.70, 0.0, 0.0]) + assert weekly["dla_sc_reported"].tolist() == pytest.approx([0.0, 72.65, 29.20]) + assert weekly["dla_m_reported"].tolist() == pytest.approx([0.0, 28.70, 0.0]) + reported = pe_person.drop(columns="winter_fuel_allowance_reported") + assert reported.to_numpy().sum() == pytest.approx( + (110.40 + 28.70 + 72.65 + 28.70 + 73.90 + 29.20) * WEEKS_IN_YEAR + ) + + def test_household_and_benunit_mapping_values_are_ported(tmp_path: Path) -> None: stage = _write_fixture(tmp_path) @@ -1162,11 +1202,12 @@ def test_household_and_benunit_mapping_values_are_ported(tmp_path: Path) -> None assert household.loc[1, "council_tax_band"] == "B" assert household.loc[1, "council_tax_rebate"] == pytest.approx(WEEKS_IN_YEAR) assert household.loc[1, "council_tax_single_adult_raw"] == 1 - # Scotland: CWATAMTD 3 (after discount) + CSEWAMT1 5 (gross) discounted at - # this household's own observed factor CWATAMTD/CWATAMT1 = 3/4, so - # 3 + 5 * 0.75 = 6.75. WATSEWRT is not asked in Scotland and is ignored. + # Scotland: the gross CWATAMT1 4 + CSEWAMT1 5; the household is a council + # tax reduction recipient with the 25% status discount, which the Water + # Charges Reduction Scheme tops up to 35%, not stacks under: 9 * 0.65. + # WATSEWRT is not asked in Scotland and is ignored. assert household.loc[1, "water_and_sewerage_charges"] == pytest.approx( - 6.75 * WEEKS_IN_YEAR + 9.0 * 0.65 * WEEKS_IN_YEAR ) assert household.loc[1, "domestic_rates"] == pytest.approx(5 * WEEKS_IN_YEAR) assert household.loc[1, "rent"] == pytest.approx(6 * WEEKS_IN_YEAR) @@ -2485,62 +2526,102 @@ def fit_weight_records(self): class TestScottishWaterAndSewerage: - """The FRS 2024-25 cell retirement, at the three shapes the tab presents. + """The charge a Scottish household pays, at the shapes the 2024-25 tab presents. - CWATAMT/CSEWAMT survive as headers in this vintage but carry no data, so a - fixture that supplies them (as the pre-#686 one did) never exercises what - the real tab does. Each case below is a real domain on the 2024-25 tab. + CWATAMT/CSEWAMT survive as headers in this vintage but carry no data; the + gross successors CWATAMT1/CSEWAMT1 carry the charge, less the household's + status discount, and the Water Charges Reduction Scheme tops a council tax + reduction recipient's discount up to 35% of the gross charges + (uk-data#499, microcosm#1095). """ @staticmethod def _frame(**columns: object) -> pd.DataFrame: - return pd.DataFrame({name: [value] for name, value in columns.items()}) - - def test_discount_factor_carries_to_the_gross_sewerage_cell(self) -> None: - # 1,641 of 1,684 Scottish households: a positive gross water bill, so - # the household's own discount factor is observable and applies to the - # sewerage side of the same bill. - frame = self._frame(CSEWAMT="", CWATAMTD=3.0, CWATAMT1=4.0, CSEWAMT1=5.0) - frame.columns = [c.lower() for c in frame.columns] - assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx(6.75) - - def test_undiscounted_household_keeps_the_gross_sewerage_charge(self) -> None: - frame = self._frame(CWATAMTD=4.0, CWATAMT1=4.0, CSEWAMT1=5.0) - frame.columns = [c.lower() for c in frame.columns] + cells = { + "CSEWAMT": "", + "CWATAMTD": 0.0, + "CWATAMT1": 0.0, + "CSEWAMT1": 0.0, + "CTDISC": 2, + "CT25D50D": "", + "CTREB": 2, + **columns, + } + frame = pd.DataFrame({name: [value] for name, value in cells.items()}) + frame.columns = [column.lower() for column in frame.columns] + return frame + + def test_undiscounted_household_pays_the_gross_charges(self) -> None: + # CWATAMTD sits below the gross water cell even without a discount, so + # it is not read where the gross cell exists. + frame = self._frame(CWATAMTD=3.0, CWATAMT1=4.0, CSEWAMT1=5.0) + assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx(9.0) + + @pytest.mark.parametrize(("code", "discount"), [(1, 0.25), (2, 0.5)]) + def test_status_discount_applies_to_both_charges(self, code, discount) -> None: + frame = self._frame(CWATAMT1=4.0, CSEWAMT1=5.0, CTDISC=1, CT25D50D=code) + assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx( + 9.0 * (1 - discount) + ) + + def test_discount_code_without_a_status_discount_is_ignored(self) -> None: + frame = self._frame(CWATAMT1=4.0, CSEWAMT1=5.0, CTDISC=2, CT25D50D=1) assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx(9.0) - def test_recorded_water_without_a_gross_bill_cell_is_not_scaled(self) -> None: + @pytest.mark.parametrize( + ("ctdisc", "code", "paid_share"), + [ + # No discount: the scheme's full 35% reduction. + (2, "", SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE), + # The single-person 25% is topped up to 35%, not stacked under it. + (1, 1, SCOTTISH_WATER_CHARGES_REDUCTION_RECIPIENT_SHARE), + # A 50% discount already exceeds the scheme's maximum. + (1, 2, 0.5), + ], + ) + def test_reduction_recipient_pays_the_larger_of_discount_and_scheme( + self, ctdisc, code, paid_share + ) -> None: + frame = self._frame( + CWATAMT1=4.0, CSEWAMT1=5.0, CTDISC=ctdisc, CT25D50D=code, CTREB=1 + ) + assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx( + 9.0 * paid_share + ) + + def test_recorded_water_without_a_gross_bill_cell_is_paid_as_recorded( + self, + ) -> None: # 22 Scottish households carry a recorded CWATAMTD with CWATAMT1 == 0; - # their CSEWAMT1 is zero too, so the fallback factor cannot move them. - frame = self._frame(CWATAMTD=3.0, CWATAMT1=0.0, CSEWAMT1=0.0) - frame.columns = [c.lower() for c in frame.columns] + # their CSEWAMT1 is zero too. + frame = self._frame(CWATAMTD=3.0, CTDISC=1, CT25D50D=1, CTREB=1) assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx(3.0) - def test_sewerage_without_an_observable_discount_is_refused(self) -> None: + def test_sewerage_without_a_gross_water_bill_is_refused(self) -> None: # The domain claim in the docstring — that a household with no gross - # water bill also carries no gross sewerage — is what makes the 1.0 - # fallback safe. A vintage refresh that breaks it must refuse at build - # time rather than silently pay sewerage at gross, which would flow - # into council_tax through the netting. - frame = self._frame(CWATAMTD=3.0, CWATAMT1=0.0, CSEWAMT1=5.0) - frame.columns = [c.lower() for c in frame.columns] - with pytest.raises(ValueError, match="no discount factor is observable"): + # water bill also carries no gross sewerage — is what makes CWATAMTD + # the whole charge there. A vintage refresh that breaks it must refuse + # at build time rather than mix the two bases. + frame = self._frame(CWATAMTD=3.0, CSEWAMT1=5.0) + with pytest.raises(ValueError, match="cannot be assembled on one basis"): scottish_water_and_sewerage_weekly(frame) def test_household_without_council_tax_cells_is_zero(self) -> None: # 21 Scottish households carry no council-tax cells at all. - frame = self._frame(CWATAMTD="", CWATAMT1="", CSEWAMT1="") - frame.columns = [c.lower() for c in frame.columns] + frame = self._frame(CWATAMTD="", CWATAMT1="", CSEWAMT1="", CTDISC="", CTREB="") assert scottish_water_and_sewerage_weekly(frame).iloc[0] == pytest.approx(0.0) + def test_missing_raw_cells_refuse(self) -> None: + frame = self._frame(CWATAMT1=4.0, CSEWAMT1=5.0).drop(columns="ctdisc") + with pytest.raises(KeyError, match="ctdisc"): + scottish_water_and_sewerage_weekly(frame) + def test_retired_cells_cannot_reintroduce_the_incumbent_zeroing(self) -> None: # The incumbent adds CSEWAMT before filling, so an all-blank CSEWAMT # propagates NaN and zeroes every Scottish household. The successor # cells must decide the answer on their own. - blank = self._frame(CSEWAMT="", CWATAMTD=3.0, CWATAMT1=4.0, CSEWAMT1=5.0) - blank.columns = [c.lower() for c in blank.columns] - absent = self._frame(CWATAMTD=3.0, CWATAMT1=4.0, CSEWAMT1=5.0) - absent.columns = [c.lower() for c in absent.columns] + blank = self._frame(CWATAMT1=4.0, CSEWAMT1=5.0) + absent = blank.drop(columns="csewamt") result = scottish_water_and_sewerage_weekly(blank).iloc[0] assert result == pytest.approx( scottish_water_and_sewerage_weekly(absent).iloc[0] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py index d1d5b4981..9371ef431 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py @@ -48,8 +48,9 @@ def test_uk_spine_graph_contains_every_manifest_stage() -> None: # pension_credit_take_up and the microcosm#1063 child_benefit_take_up; the # frs_hmrc_retained_leaves / hmrc_spi_income certified-pair alternatives # are retired (#901), so the manifest roster is the graph roster. - # microcosm#1063 also adds cgt_residential_split after the anchor. - assert len(expected) == 38 + # microcosm#1063 also adds cgt_residential_split after the anchor, and + # microcosm#1095 the spi_benefit_coherence pass after uc_reporter_redraw. + assert len(expected) == 39 assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(expected) assert set(expected) <= ids assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(ids) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_hmrc_income_source_manifest.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_hmrc_income_source_manifest.py index 4661ad508..d13df602b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_hmrc_income_source_manifest.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_hmrc_income_source_manifest.py @@ -126,7 +126,6 @@ def test_official_hmrc_sources_and_sampling_weights_remain_bound(): (INCOME, "fit_weighted_qrf_stage1", "source_columns", {}, "source_columns"), (INCOME, "fit_weighted_qrf_stage1", "seed", 43, "seed drifted"), (INCOME, "fit_weighted_qrf_stage2", "predictors", ["age"], "stage2.predictors"), - (INCOME, "redraw_columns_from_fitted_qrf", "rows", "all", "base redraw"), ( INCOME, "materialize_hmrc_income_bands_fail_closed", diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_identity_stability_receipts.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_identity_stability_receipts.py index af618acc9..6b4d9687b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_identity_stability_receipts.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_identity_stability_receipts.py @@ -241,6 +241,7 @@ def materialize(self, frame, variables, period): "person_household_id": [100], "age": [float(UK_AGE_TOP_CODE)], "gender": ["FEMALE"], + "is_uc_claimant": [True], } ), benunit=pd.DataFrame({"benunit_id": [10], "benunit_household_id": [100]}), diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_ladder_targets.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_ladder_targets.py index 74665da84..6e39553c3 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_ladder_targets.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_ladder_targets.py @@ -188,6 +188,7 @@ def __init__(self, values): class FakeUKSimulation: person_household = np.asarray([0, 0, 1, 2]) + person_benunit = np.asarray([0, 0, 1, 2]) benunit_household = np.asarray([0, 1, 2]) data = { "household_id": [101, 102, 103], @@ -196,7 +197,13 @@ class FakeUKSimulation: "income_tax": [1.0, 0.0, 2.0, 3.0], "age": [5, 35, 72, 12], "universal_credit": [0.0, 100.0, 50.0], - "num_children": [1, 0, 2], + "is_uc_claimant": [False, True, True, False], + "is_child_or_qualifying_young_person_for_universal_credit": [ + True, + False, + False, + True, + ], "is_child": [1.0, 0.0, 0.0, 1.0], } @@ -206,11 +213,14 @@ def calculate(self, variable, **_kwargs): def map_result(self, values, from_entity, to_entity): values = np.asarray(values, dtype=float) out = np.zeros(3, dtype=float) - mapping = ( - self.person_household - if from_entity == "person" - else self.benunit_household - ) + if to_entity == "benunit": + mapping = self.person_benunit + else: + mapping = ( + self.person_household + if from_entity == "person" + else self.benunit_household + ) for index, household_index in enumerate(mapping): out[household_index] += values[index] return out diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_local_targets.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_local_targets.py index c121caccd..c03415367 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_local_targets.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_local_targets.py @@ -20,6 +20,7 @@ def __init__(self, values): class FakeUKSimulation: def __init__(self): self.person_household = np.asarray([0, 0, 1, 2]) + self.person_benunit = np.asarray([0, 0, 1, 2]) self.benunit_household = np.asarray([0, 1, 2]) self.data = { "household_id": [101, 102, 103], @@ -28,7 +29,15 @@ def __init__(self): "income_tax": [1.0, 0.0, 2.0, 3.0], "age": [5, 35, 72, 12], "universal_credit": [0.0, 100.0, 50.0], - "num_children": [0, 0, 1], + # Benefit unit 2's only member is a 12-year-old the FRS records as + # a dependant: the UC family type counts one child there. + "is_uc_claimant": [False, True, True, False], + "is_child_or_qualifying_young_person_for_universal_credit": [ + True, + False, + False, + True, + ], "is_child": [1.0, 0.0, 0.0, 1.0], "equiv_hbai_household_net_income": [100.0, 200.0, 300.0], "equiv_hbai_household_net_income_ahc": [80.0, 150.0, 260.0], @@ -45,8 +54,14 @@ def calculate(self, variable, **_kwargs): return Result(self.data[variable]) def map_result(self, values, from_entity, to_entity): - assert to_entity == "household" values = np.asarray(values, dtype=float) + if to_entity == "benunit": + assert from_entity == "person" + out = np.zeros(len(self.benunit_household), dtype=float) + for i, benunit_index in enumerate(self.person_benunit): + out[benunit_index] += values[i] + return out + assert to_entity == "household" out = np.zeros(3, dtype=float) if from_entity == "person": for i, household_index in enumerate(self.person_household): @@ -202,22 +217,51 @@ def test_compute_constituency_household_metrics() -> None: def test_uc_child_bands_sum_uc_benefit_units_to_household() -> None: class MultiBenunitUKSimulation(FakeUKSimulation): def __init__(self): - self.person_household = np.asarray([0, 0]) + # Three benefit units in one household: a claimant with one, three + # and two children (the last two are 19 and 18, qualifying young + # people the engine's age-18 count would drop). + self.person_benunit = np.asarray([0, 0, 1, 1, 1, 1, 2, 2, 2]) + self.person_household = np.zeros(9, dtype=int) self.benunit_household = np.asarray([0, 0, 0]) self.data = { "household_id": [101], - "self_employment_income": [0.0, 0.0], - "employment_income": [0.0, 0.0], - "income_tax": [0.0, 0.0], - "age": [35, 10], + "self_employment_income": [0.0] * 9, + "employment_income": [0.0] * 9, + "income_tax": [0.0] * 9, + "age": [35, 10, 40, 3, 6, 9, 45, 19, 18], "universal_credit": [100.0, 50.0, 0.0], - "num_children": [1, 3, 2], - "is_child": [0.0, 1.0], + "is_uc_claimant": [ + True, + False, + True, + False, + False, + False, + True, + False, + False, + ], + "is_child_or_qualifying_young_person_for_universal_credit": [ + False, + True, + False, + True, + True, + True, + False, + True, + True, + ], + "is_child": [0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], } def map_result(self, values, from_entity, to_entity): - assert to_entity == "household" values = np.asarray(values, dtype=float) + if to_entity == "benunit": + out = np.zeros(3, dtype=float) + for index, benunit_index in enumerate(self.person_benunit): + out[benunit_index] += values[index] + return out out = np.zeros(1, dtype=float) links = ( self.person_household diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py index 42b6c737a..80c888e2c 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py @@ -63,6 +63,9 @@ UC_REPORTER_REDRAW_STAGE_NAMES = [ "uc_reporter_redraw", ] +SPI_BENEFIT_COHERENCE_STAGE_NAMES = [ + "spi_benefit_coherence", +] UC_COHERENCE_STAGE_NAMES = [ "uc_capital_coherence", ] @@ -99,6 +102,7 @@ *E5_STAGE_NAMES, *E6_STAGE_NAMES, *UC_REPORTER_REDRAW_STAGE_NAMES, + *SPI_BENEFIT_COHERENCE_STAGE_NAMES, *UC_COHERENCE_STAGE_NAMES, *PENSION_CREDIT_TAKE_UP_STAGE_NAMES, *CHILD_BENEFIT_TAKE_UP_STAGE_NAMES, @@ -169,6 +173,7 @@ def test_e5_and_e6_follow_e7_and_precede_the_uc_rewrites(self) -> None: *E5_STAGE_NAMES, *E6_STAGE_NAMES, *UC_REPORTER_REDRAW_STAGE_NAMES, + *SPI_BENEFIT_COHERENCE_STAGE_NAMES, *UC_COHERENCE_STAGE_NAMES, *PENSION_CREDIT_TAKE_UP_STAGE_NAMES, *CHILD_BENEFIT_TAKE_UP_STAGE_NAMES, @@ -242,6 +247,7 @@ def test_country_stage_plan_assembles_spine_plan(self) -> None: "hmrc_spi_income_spine": _identity, "spi_housing_shell": _identity, "uc_reporter_redraw": _identity, + "spi_benefit_coherence": _identity, "uc_capital_coherence": _identity, "pension_credit_take_up": _identity, "child_benefit_take_up": _identity, @@ -651,7 +657,6 @@ def test_e3_operation_kinds_are_declared_in_order(self) -> None: "resample_band_donor_leaves", "fit_weighted_qrf_stage2", "zero_pension_age_reports_below_state_pension_age", - "redraw_columns_from_fitted_qrf", "materialize_hmrc_income_bands_fail_closed", "classify_hmrc_income_facts_with_reviewed_fences", "gate_distributional_effective_mass", @@ -726,7 +731,11 @@ def test_engine_predictor_and_rewrite_constants_match_manifest(self) -> None: from microcosm.build.uk_runtime.etb_services import ( UK_ETB_SERVICES_OUTPUT_COLUMNS, ) - from microcosm.build.uk_runtime.etb_vat import UK_ETB_VAT_PREDICTORS + from microcosm.build.uk_runtime.etb_vat import ( + UK_ETB_FAMILY_ROLE_COUNTS, + UK_ETB_VAT_ENGINE_PREDICTORS, + UK_ETB_VAT_PREDICTORS, + ) from microcosm.build.uk_runtime.frs_brma import UK_BRMA_PREDICTORS from microcosm.build.uk_runtime.frs_education_grants import ( DISABLED_STUDENTS_ALLOWANCE_ELIGIBILITY_VARIABLES, @@ -819,6 +828,10 @@ def test_engine_predictor_and_rewrite_constants_match_manifest(self) -> None: ) assert ( tuple(stages["etb_vat"].operations[1].parameters["predictors"]) + == UK_ETB_VAT_ENGINE_PREDICTORS + ) + assert ( + tuple(stages["etb_vat"].operations[2].parameters["predictors"]) == UK_ETB_VAT_PREDICTORS ) from microcosm.build.uk_runtime.etb_services import ( @@ -832,7 +845,7 @@ def test_engine_predictor_and_rewrite_constants_match_manifest(self) -> None: ) assert set( stages["etb_services"].operations[2].parameters["derived_predictors"] - ) == set(UK_ETB_SERVICES_EDUCATION_COUNTS) + ) == {*UK_ETB_SERVICES_EDUCATION_COUNTS, *UK_ETB_FAMILY_ROLE_COUNTS} assert ( tuple(stages["etb_services"].operations[3].parameters["targets"]) == UK_ETB_SERVICES_OUTPUT_COLUMNS[:3] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_band_donors.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_band_donors.py index 4631e5e4c..dcef9e62a 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_band_donors.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_band_donors.py @@ -24,6 +24,7 @@ SPI_INCOME_BAND_MINIMUM_DONORS, UKSPIIncomeBandDonorStageTransform, _assert_band_donor_stage_parameters, + age_band_lower_bound, income_band_lower_bound, load_hmrc_itl_band_taxpayers, spi_income_band_donor_operation_parameters, @@ -146,14 +147,26 @@ def _raw_tape(rows: int = 240, *, seed: int = 0) -> pd.DataFrame: return pd.DataFrame(records) -def _support_frame(n_households: int = 60, *, reverse: bool = False): +def _support_frame( + n_households: int = 60, + *, + reverse: bool = False, + dependant_age: int = 12, + dependant_is_claimant: bool = False, +): ids = np.arange(1, n_households + 1, dtype="int64") person = pd.DataFrame( { "person_id": np.r_[ids, ids + 1_000], "person_benunit_id": np.r_[ids, ids], "person_household_id": np.r_[ids, ids], - "age": np.r_[np.full(n_households, 45), np.full(n_households, 12)], + "age": np.r_[ + np.full(n_households, 45), np.full(n_households, dependant_age) + ], + "is_uc_claimant": np.r_[ + np.ones(n_households, dtype=bool), + np.full(n_households, dependant_is_claimant, dtype=bool), + ], "gender": np.r_[ np.where(ids % 2 == 0, "MALE", "FEMALE"), np.full(n_households, "FEMALE"), @@ -393,6 +406,38 @@ def test_stack_is_keyed_on_identity_and_refuses_a_second_stack() -> None: _stack_small(first.frame) +def test_dependants_aged_16_to_19_are_never_carriers() -> None: + """A dependant keeps its twin's values, so it cannot carry a band draw. + + The second member of every household is 17 and the tape favours that age + band; only claimants and partners are candidates (uk-data#504, + microcosm#1095), so the 17-year-olds are seated only when the frame flags + them as claimants or partners. + """ + + propensity = _propensity() + teen_band = int(age_band_lower_bound(np.asarray([17.0]))[0]) + favoured = ( + propensity.assign(age_band=teen_band, propensity=1.0) + .drop_duplicates(["region", "gender", "age_band", "band"]) + .reset_index(drop=True) + ) + propensity = pd.concat( + [propensity.loc[propensity["age_band"] != teen_band], favoured], + ignore_index=True, + ) + + def carrier_ages(*, dependant_is_claimant: bool) -> pd.Series: + frame = _support_frame( + 200, dependant_age=17, dependant_is_claimant=dependant_is_claimant + ) + person = _stack_small(frame, propensity=propensity).frame.table("person") + return person.loc[person[PERSON_IS_SPI_INCOME_BAND_CARRIER], "age"] + + assert carrier_ages(dependant_is_claimant=False).eq(45).all() + assert carrier_ages(dependant_is_claimant=True).eq(17).any() + + def test_stack_follows_weight_times_propensity_not_the_sample() -> None: # Given a tape whose band propensities are equal across the two regions, # seats follow household weight: the heavier half of the frame is seated @@ -623,7 +668,7 @@ def draw(frame: pd.DataFrame) -> pd.Series: assert renumbered.sort_index().equals(first.sort_index()) -def test_resample_refuses_missing_carriers_or_undeclared_band() -> None: +def test_resample_refuses_missing_carriers_undeclared_band_or_non_recipient() -> None: donor = prepare_spi_donor_table(_raw_tape(), seed=1) household = pd.DataFrame( { @@ -652,6 +697,18 @@ def test_resample_refuses_missing_carriers_or_undeclared_band() -> None: regional_pool_minimum=5, seed=1, ) + household[SPI_INCOME_BAND_DONOR_LOWER_BOUND_COLUMN] = 200_000.0 + with pytest.raises(ValueError, match="must be SPI recipients"): + _resample_band_donor_leaves( + person, + donor, + household=household, + spi_people=pd.Series([False]), + uprating_factors=dict.fromkeys(SPI_INCOME_QRF_OUTPUT_COLUMNS, 1.0), + lower_bounds=BANDS, + regional_pool_minimum=5, + seed=1, + ) person[PERSON_IS_SPI_INCOME_BAND_CARRIER] = False with pytest.raises(ValueError, match="no reserved carriers"): _resample_band_donor_leaves( diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_benefit_coherence.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_benefit_coherence.py new file mode 100644 index 000000000..d809b7323 --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_benefit_coherence.py @@ -0,0 +1,367 @@ +"""The SPI-channel benefit coherence pass (microcosm#1095, uk-data#514).""" + +from __future__ import annotations + +import numpy as np +import pandas as pd +import pytest + +from microcosm.build.country_spec import load_country_spec +from microcosm.build.source_manifest import SourceStageSpec +from microcosm.build.uk_runtime import frs_disability +from microcosm.build.uk_runtime.frs_take_up import UKTakeUpPopulationPolicy +from microcosm.build.uk_runtime.national_frame import uk_national_frame +from microcosm.build.uk_runtime.spi_benefit_coherence import ( + SPI_BENEFIT_COHERENCE_STAGE_NAME, + SPI_RESTORED_REPORT_COLUMNS, + SPI_ZEROED_REPORT_COLUMNS, + apply_spi_benefit_coherence, + assert_spi_benefit_coherence_stage_parameters, +) +from microcosm.build.uk_runtime.spi_support import ( + support_channel_column, + support_source_id_column, +) +from microcosm.frame import WeightKind + +CATEGORY_RATES = frs_disability.UKDWPDisabilityCategoryRates( + aa_lower=72.65, + aa_higher=108.55, + dla_sc_lower=28.70, + dla_sc_middle=72.65, + dla_sc_higher=108.55, + dla_m_lower=28.70, + dla_m_higher=75.75, + pip_m_standard=28.70, + pip_m_enhanced=75.75, + pip_dl_standard=72.65, + pip_dl_enhanced=108.55, + instant="2024-01-01", + source="test", +) +FLAG_RATES = frs_disability.UKDWPDisabilityFlagRates( + aa_higher=108.55, + dla_sc_higher=108.55, + pip_dl_enhanced=108.55, + instant="2024-01-01", + source="test", +) +POLICY = UKTakeUpPopulationPolicy( + adult_age=18, state_pension_age=66, instant="2024-01-01", source="test" +) + + +class _Contract: + def rate(self, key: str) -> float: + assert key == "universal_credit" + return 0.55 + + +REPORT_COLUMNS = tuple( + dict.fromkeys( + ( + *SPI_ZEROED_REPORT_COLUMNS, + *SPI_RESTORED_REPORT_COLUMNS, + *frs_disability.UK_DISABILITY_FLAG_REPORTED_COLUMNS, + "universal_credit_reported", + ) + ) +) + + +def _person( + person_id, benunit_id, household_id, channel, source_id, age, **reports +) -> dict: + row = { + "person_id": person_id, + "person_benunit_id": benunit_id, + "person_household_id": household_id, + "age": age, + support_channel_column("person"): channel, + support_source_id_column("person"): source_id, + } + row.update(dict.fromkeys(REPORT_COLUMNS, 0.0)) + row.update(reports) + return row + + +def _frame(*, base_own_right_override: bool | None = None): + people = [ + # FRS twins. Person 11 reports UC and IIDB; person 21 reports JSA and + # AFCS; person 31 is a pensioner reporting bereavement support. + _person( + 11, + 1, + 1, + "frs", + 11, + 40, + universal_credit_reported=900.0, + iidb_reported=500.0, + ), + _person( + 21, 2, 2, "frs", 21, 35, jsa_contrib_reported=300.0, afcs_reported=800.0 + ), + _person(31, 3, 3, "frs", 31, 70, bsp_reported=1200.0), + # SPI copies with drawn reports; their source ids name the twins. + _person( + 105, + 50, + 5, + "spi", + 11, + 40, + jsa_contrib_reported=2_000.0, + iidb_reported=9_999.0, + income_support_reported=400.0, + sda_reported=100.0, + ), + _person( + 106, + 60, + 6, + "spi", + 21, + 35, + universal_credit_reported=1_200.0, + working_tax_credit_reported=300.0, + afcs_reported=0.0, + bsp_reported=650.0, + ), + _person( + 107, + 70, + 7, + "spi", + 31, + 70, + ssmg_reported=500.0, + child_tax_credit_reported=50.0, + ), + ] + person = pd.DataFrame(people) + rule = ( + person[ + [ + "universal_credit_reported", + "jsa_contrib_reported", + "jsa_income_reported", + "esa_contrib_reported", + "esa_income_reported", + ] + ].sum(axis=1) + > 0 + ) + # The twins' stored flag follows the rule; the SPI copies keep the twin's. + twin_flag = dict(zip(person["person_id"], rule, strict=True)) + person["receives_benefits_in_own_right"] = [ + twin_flag[source] for source in person[support_source_id_column("person")] + ] + if base_own_right_override is not None: + person.loc[0, "receives_benefits_in_own_right"] = base_own_right_override + derived = frs_disability.derive_frs_disability( + person, category_rates=CATEGORY_RATES, flag_rates=FLAG_RATES + ) + for column in frs_disability.FRS_DISABILITY_OUTPUT_COLUMNS: + person[column] = derived[column].to_numpy() + benunit = pd.DataFrame( + { + "benunit_id": [1, 2, 3, 50, 60, 70], + support_channel_column("benunit"): [ + "frs", + "frs", + "frs", + "spi", + "spi", + "spi", + ], + # Every SPI unit inherited a claim from its twin. + "would_claim_uc": [True, True, False, True, True, True], + } + ) + household = pd.DataFrame({"household_id": [1, 2, 3, 5, 6, 7]}) + return uk_national_frame( + person=person, + benunit=benunit, + household=household, + household_weights=np.asarray([10.0, 20.0, 30.0, 1.0, 2.0, 3.0]), + weight_kind=WeightKind.IMPORTANCE, + time_period="2024", + ) + + +def _apply(frame): + return apply_spi_benefit_coherence( + frame, + contract=_Contract(), + population_policy=POLICY, + category_rates=CATEGORY_RATES, + flag_rates=FLAG_RATES, + ) + + +def test_spi_rows_lose_out_of_work_and_legacy_reports() -> None: + result = _apply(_frame()) + person = result.frame.table("person").set_index("person_id") + + for column in SPI_ZEROED_REPORT_COLUMNS: + assert (person.loc[[105, 106, 107], column] == 0.0).all(), column + assert person.loc[21, "jsa_contrib_reported"] == 300.0 + assert result.zeroed["jsa_contrib_reported"]["rows_reporting_before"] == 1 + assert all( + receipt["rows_reporting_after"] == 0 for receipt in result.zeroed.values() + ) + + +def test_spi_rows_lose_income_related_esa_and_keep_contributory_esa() -> None: + # policyengine-uk pays a drawn income-related ESA report as the award, + # behind a capital test alone, whatever the copy's new incomes; contributory + # ESA is open to new claims and not income-tested, so the copy keeps it. + frame = _frame() + person = frame.table("person").copy() + copy = person["person_id"] == 106 + person.loc[copy, "esa_income_reported"] = 600.0 + person.loc[copy, "esa_contrib_reported"] = 700.0 + drawn = uk_national_frame( + person=person, + benunit=frame.table("benunit"), + household=frame.table("household"), + household_weights=frame.weights_for("household").values, + weight_kind=WeightKind.IMPORTANCE, + time_period="2024", + ) + result = _apply(drawn) + after = result.frame.table("person").set_index("person_id") + + assert after.loc[106, "esa_income_reported"] == 0.0 + assert after.loc[106, "esa_contrib_reported"] == 700.0 + assert result.zeroed["esa_income_reported"]["rows_reporting_before"] == 1 + assert "esa_contrib_reported" not in result.zeroed + + +def test_spi_rows_take_injury_service_and_bereavement_reports_from_their_twin() -> None: + result = _apply(_frame()) + person = result.frame.table("person").set_index("person_id") + + assert person.loc[105, "iidb_reported"] == 500.0 + assert person.loc[106, "afcs_reported"] == 800.0 + assert person.loc[106, "bsp_reported"] == 0.0 + assert person.loc[107, "bsp_reported"] == 1200.0 + assert all( + receipt["rows_differing_from_twin_after"] == 0 + for receipt in result.restored.values() + ) + + +def test_twin_restore_follows_source_ids_not_row_order() -> None: + frame = _frame() + shuffled = frame.table("person").sample(frac=1.0, random_state=7) + reordered = uk_national_frame( + person=shuffled.reset_index(drop=True), + benunit=frame.table("benunit"), + household=frame.table("household"), + household_weights=frame.weights_for("household").values, + weight_kind=WeightKind.IMPORTANCE, + time_period="2024", + ) + person = _apply(reordered).frame.table("person").set_index("person_id") + + assert person.loc[105, "iidb_reported"] == 500.0 + assert person.loc[107, "bsp_reported"] == 1200.0 + + +def test_benefits_in_own_right_follow_the_rows_own_reports() -> None: + result = _apply(_frame()) + person = result.frame.table("person").set_index("person_id") + + # 105 inherited True (twin reports UC) but its only own report was JSA, + # now zeroed; 106 reports UC on its own; 107 reports none. + assert not person.loc[105, "receives_benefits_in_own_right"] + assert person.loc[106, "receives_benefits_in_own_right"] + assert not person.loc[107, "receives_benefits_in_own_right"] + assert result.benefits_in_own_right["mismatches_after"] == 0 + + +def test_a_base_row_that_disagrees_with_its_own_reports_refuses() -> None: + with pytest.raises(ValueError, match="FRS-channel person"): + _apply(_frame(base_own_right_override=False)) + + +def test_disability_flags_follow_the_final_reports() -> None: + before = _frame().table("person").set_index("person_id") + person = _apply(_frame()).frame.table("person").set_index("person_id") + + # SDA (zeroed) no longer flags 105; its restored IIDB flags it instead. + assert before.loc[105, "is_disabled_for_benefits"] + assert person.loc[105, "is_disabled_for_benefits"] + # 106 drew no AFCS but its twin reports it. + assert not before.loc[106, "is_disabled_for_benefits"] + assert person.loc[106, "is_disabled_for_benefits"] + + +def test_spi_universal_credit_take_up_follows_the_units_own_reports() -> None: + result = _apply(_frame()) + benunit = result.frame.table("benunit").set_index("benunit_id") + + # 60 reports UC; 70 is a pensioner unit outside the population and reports + # nothing; base units keep their flags. + assert benunit.loc[60, "would_claim_uc"] + assert not benunit.loc[70, "would_claim_uc"] + assert benunit.loc[[1, 2, 3], "would_claim_uc"].tolist() == [True, True, False] + assert result.universal_credit_take_up["reporters_not_claiming"] == 0 + assert ( + result.universal_credit_take_up["outside_population_non_reporters_claiming"] + == 0 + ) + + +def test_base_rows_are_never_modified() -> None: + frame = _frame() + result = _apply(frame) + for entity in ("person", "benunit"): + before = frame.table(entity) + after = result.frame.table(entity) + channel = support_channel_column(entity) + base = before[channel] == "frs" + pd.testing.assert_frame_equal( + before.loc[base].reset_index(drop=True), + after.loc[after[channel] == "frs"].reset_index(drop=True), + ) + + +def test_the_pass_is_idempotent() -> None: + once = _apply(_frame()).frame + twice = _apply(once).frame + for entity in ("person", "benunit", "household"): + pd.testing.assert_frame_equal(once.table(entity), twice.table(entity)) + + +def _committed_stage() -> SourceStageSpec: + spec = load_country_spec("uk") + return next( + stage + for stage in spec.sources.stages + if stage.stage == SPI_BENEFIT_COHERENCE_STAGE_NAME + ) + + +def test_committed_manifest_declares_the_stage_the_code_runs() -> None: + stage = _committed_stage() + assert_spi_benefit_coherence_stage_parameters(stage) + names = [entry.stage for entry in load_country_spec("uk").sources.stages] + # After the last UC report writer, before every UC, PC and CB consumer. + position = names.index(SPI_BENEFIT_COHERENCE_STAGE_NAME) + assert names[position - 1] == "uc_reporter_redraw" + assert names[position + 1] == "uc_capital_coherence" + + +def test_manifest_drift_refuses() -> None: + stage = _committed_stage() + operations = [ + {"kind": operation.kind, **dict(operation.parameters)} + for operation in stage.operations + ] + operations[0]["columns"] = operations[0]["columns"][:-1] + drifted = SourceStageSpec.from_mapping({**stage.__dict__, "operations": operations}) + with pytest.raises(ValueError, match="operations drifted"): + assert_spi_benefit_coherence_stage_parameters(drifted) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_spine.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_spine.py index bdadfd4e4..4738624af 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_spine.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_spine.py @@ -54,6 +54,7 @@ def _base_frame(*, time_period: str = "2023") -> object: "person_benunit_id": [201, 101], "age": [44, 40], "gender": ["FEMALE", "MALE"], + "is_uc_claimant": [True, True], "employment_income": [20.0, 10.0], "self_employment_income": [0.0, 0.0], "savings_interest_income": [2.0, 1.0], @@ -407,7 +408,7 @@ def _synthetic_hmrc_targets(path: Path) -> HMRCIncomeTargetSet: ) -def test_spi_income_zero_initializes_frs_charity_and_redraws_dividends_after_stage2( +def test_spi_income_zero_initializes_frs_charity_and_keeps_frs_dividends( tmp_path: Path, monkeypatch: pytest.MonkeyPatch, ) -> None: @@ -452,7 +453,6 @@ def test_spi_income_zero_initializes_frs_charity_and_redraws_dividends_after_sta "gift_aid": 0.0, "charitable_investment_gifts": 0.0, }, - stage1_base_redraw_columns=("dividend_income",), ) person = result.person base = person[support_channel_column("person")] != SPI_SYNTHETIC_SUPPORT_CHANNEL @@ -464,7 +464,14 @@ def test_spi_income_zero_initializes_frs_charity_and_redraws_dividends_after_sta # stage-time zero — the explicit initialization above and this fill are # now the same semantics, and the artifact ships no NaN. assert person.loc[base, "hmrc_spi_employment_benefits"].eq(0.0).all() - assert person.loc[base, "dividend_income"].tolist() == [100.0, 101.0] + # FRS rows keep their reported dividends (uk-data#498, microcosm#1095). + reported = support.person[support_channel_column("person")] != ( + SPI_SYNTHETIC_SUPPORT_CHANNEL + ) + assert ( + person.loc[base, "dividend_income"].tolist() + == support.person.loc[reported, "dividend_income"].tolist() + ) assert person.loc[spi, "dividend_income"].tolist() == [100.0, 101.0] assert _FakeQRF.events[1][0] == "stage2" assert _FakeQRF.events[1][2] == [20.0, 10.0] @@ -675,13 +682,47 @@ def test_income_stage_parameters_accept_the_committed_manifest() -> None: ) -def test_income_stage_parameters_refuse_redraw_column_drift() -> None: +def test_income_stage_parameters_refuse_a_base_channel_redraw() -> None: + stage = _committed_stage("hmrc_spi_income_spine") + operations = [ + {"kind": operation.kind, **dict(operation.parameters)} + for operation in stage.operations + ] + operations.append( + { + "kind": "redraw_columns_from_fitted_qrf", + "fit": "stage1", + "columns": ["dividend_income"], + "rows": "base_support_channel", + } + ) + stage = SourceStageSpec.from_mapping({**stage.__dict__, "operations": operations}) + with pytest.raises(ValueError, match="must not redraw FRS-channel incomes"): + _assert_income_stage_parameters( + stage, seed=42, qrf_estimators=100, donor_sample_size=100_000 + ) + + +@pytest.mark.parametrize( + ("kind", "parameter", "value", "message"), + [ + ("fit_weighted_qrf_stage1", "recipient_role_column", None, "recipient role"), + ("fit_weighted_qrf_stage1", "recipient_role_column", "is_adult", "role"), + ( + "fit_weighted_qrf_stage2", + "target_population", + "spi_synthetic_support_channel", + "target population", + ), + ], +) +def test_income_stage_parameters_refuse_a_recipient_domain_drift( + kind, parameter, value, message +) -> None: stage = _with_mutated_operation( - _committed_stage("hmrc_spi_income_spine"), - "redraw_columns_from_fitted_qrf", - columns=["savings_interest_income"], + _committed_stage("hmrc_spi_income_spine"), kind, **{parameter: value} ) - with pytest.raises(ValueError, match="base redraw columns drifted"): + with pytest.raises(ValueError, match=message): _assert_income_stage_parameters( stage, seed=42, qrf_estimators=100, donor_sample_size=100_000 ) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py index 7e9ac477d..e412f9c81 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py @@ -115,6 +115,10 @@ def _apply_pending_roster_transformations( # post-SPI incomes, right after the Pension Credit redraw. assert "child_benefit_take_up" not in roster roster.insert(roster.index("pension_credit_take_up") + 1, "child_benefit_take_up") + # microcosm#1095 re-mint pending: the SPI benefit pass runs after the last + # UC report writer and before every UC, PC and CB consumer. + assert "spi_benefit_coherence" not in roster + roster.insert(roster.index("uc_reporter_redraw") + 1, "spi_benefit_coherence") # microcosm#1063 re-mint pending: the residential split carries the flag # as weight after the anchor, and the asset-type stage types its arms. assert "cgt_residential_split" not in roster diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py index 5c2256852..8d3434b83 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_stage_health.py @@ -1907,6 +1907,71 @@ def gate(*bands): assert committed["check"] == "pension_credit_take_up" +def test_spi_benefit_coherence_gate_holds_the_structural_zeros() -> None: + gates = json.loads( + (_TEST_PATHS.package / "src/microcosm/build/uk/gates.json").read_text("utf-8") + ) + entry = next( + g for g in gates["gates"] if g["id"] == "uk_stage_spi_benefit_coherence" + ) + assert entry["criticality"] == "release_blocking" + assert entry["evidence_absent_blocks"] is True + parameters = dict(entry["parameters"]) + + def evidence(): + return { + "stage": "spi_benefit_coherence", + "zeroed": { + column: {"rows_reporting_before": 3, "rows_reporting_after": 0} + for column in parameters["zeroed_columns"] + }, + "restored": { + column: {"rows_differing_from_twin_after": 0} + for column in parameters["restored_columns"] + }, + "benefits_in_own_right": {"mismatches_after": 0, "spi_rows_changed": 2}, + "universal_credit_take_up": { + "reporters_not_claiming": 0, + "outside_population_non_reporters_claiming": 0, + "spi_claiming_before": 5, + "spi_claiming_after": 4, + }, + "base_rows_unchanged": True, + } + + def gate(payload): + return uk_stage_health_gate( + evidence=payload, + stage="spi_benefit_coherence", + check="spi_benefit_coherence", + parameters=parameters, + ) + + assert _passed(gate(evidence())) + broken = [] + payload = evidence() + payload["zeroed"]["sda_reported"]["rows_reporting_after"] = 1 + broken.append(payload) + payload = evidence() + del payload["zeroed"]["ssmg_reported"] + broken.append(payload) + payload = evidence() + payload["restored"]["iidb_reported"]["rows_differing_from_twin_after"] = 2 + broken.append(payload) + payload = evidence() + payload["benefits_in_own_right"]["mismatches_after"] = 1 + broken.append(payload) + payload = evidence() + payload["base_rows_unchanged"] = False + broken.append(payload) + for key in ("reporters_not_claiming", "outside_population_non_reporters_claiming"): + payload = evidence() + payload["universal_credit_take_up"][key] = 1 + broken.append(payload) + for payload in broken: + assert not gate(payload).passed + + def test_child_benefit_take_up_holds_claims_by_age_and_the_opt_out_share() -> None: parameters = { "stage": "child_benefit_take_up", diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py index da447d30e..109c66366 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_terminal_gates.py @@ -467,18 +467,14 @@ def test_committed_target_fit_register_retains_only_live_deferrals() -> None: # deferral (ruling D6) is retired in turn (microcosm#1069): with the SPI # channel's State Pension at 66 repaired the row fits at +23.0 % to +24.0 % # across the c5-fix and c6 arms, back inside the bound. The SE - # 12,570-15,000 cell is deferred again on the microcosm#1063 stack - # (2026-10-02, four weeks): its design-weight value sits on the target and - # the solver's pull, the same as main's, crosses the bound at +32.0 %. - assert set(register) == { - "hmrc.spi_region.income_tax_by_region_12570_15000@E12000008@2025" - } - deferral = register[ - "hmrc.spi_region.income_tax_by_region_12570_15000@E12000008@2025" - ] - assert deferral.approved_on == "2026-10-02" - assert deferral.expires_on == "2026-11-02" - assert "microcosm#1063" in deferral.adjudication + # 12,570-15,000 cell was deferred again on the microcosm#1063 stack + # (2026-10-02, four weeks): its design-weight value sat on the target and + # the solver's pull, the same as main's, crossed the bound at +32.0 %. It + # is retired with the microcosm#1095 ports: with FRS respondents keeping + # their reported dividends and SPI draws going to claimants and partners + # only, the cell fits at +11.7 % on the rebased head, and the gate fails + # the deferral as stale. + assert register == {} # Aggregate errors from the fresh UC #882 development run: 1,500 epochs with diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_uc_capital_coherence.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_uc_capital_coherence.py index dba1371d9..937062935 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_uc_capital_coherence.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_uc_capital_coherence.py @@ -3,6 +3,8 @@ # ruff: noqa: F403, F405 from test_support.microcosm_build.uk_uc_capital_coherence import * +RECEIPTS = ("coarsening_levels", "capital_against_investment_income") + def test_manifest_declares_exact_redraw_seed_and_output() -> None: stage = _stage() @@ -16,6 +18,12 @@ def test_manifest_declares_exact_redraw_seed_and_output() -> None: assert redraw.parameters["seed"] == UC_CAPITAL_REDRAW_SEED assert redraw.parameters["salt"] == UC_CAPITAL_REDRAW_SALT assert redraw.parameters["couple_status"] == "is_uc_couple" + assert redraw.parameters["rows"] == "spi_channel" + assert redraw.parameters["minimum_cell_donors"] == UC_CAPITAL_MINIMUM_CELL_DONORS + assert redraw.parameters["coarsening"] == list(UC_CAPITAL_COARSENING) + assert redraw.parameters["investment_income_band_edges"] == list( + UC_CAPITAL_INCOME_BAND_EDGES + ) assert stage.outputs == ("uc_reported_capital",) assert stage.rewrites == ("frs_benunit_capital", "would_claim_uc") @@ -84,16 +92,24 @@ def test_or_refresh_truth_table_and_same_capital_source() -> None: def test_redraw_is_reporter_conditioned_cell_exact_and_household_weighted() -> None: - result = cohere_uc_capital(_frame()) + result = cohere_uc_capital(_frame(), minimum_cell_donors=1) benunit = result.frame.table("benunit").set_index("benunit_id") # benunit 1005's identity draw is 0.364. The weighted donor CDF is # [0.1, 1.0], so it selects 200; an unweighted draw would select 100. assert benunit.loc[1005, "frs_benunit_capital"] == 200.0 assert benunit.loc[1007, "frs_benunit_capital"] == 3_000.0 - assert benunit.loc[1006, "frs_benunit_capital"] == 888_888.0 + # The SPI non-reporter is redrawn too, from the base non-reporters of its + # cell (777,777 and 999,999 at equal weight): its copied answer is gone. + draw = stable_identity_uniforms( + np.asarray([1006]), seed=UC_CAPITAL_REDRAW_SEED, salt=UC_CAPITAL_REDRAW_SALT + )[0] + expected = 777_777.0 if draw < 0.5 else 999_999.0 + assert benunit.loc[1006, "frs_benunit_capital"] == expected assert benunit.loc[401, "frs_benunit_capital"] == 999_999.0 assert result.redrawn_spi_reporter_count == 2 + assert result.redrawn_spi_benefit_units == 3 + assert result.coarsening_levels["exact_cell"] == 3 def test_capital_donor_cells_use_claimant_partnership_and_preserve_marital_status(): @@ -105,7 +121,7 @@ def test_capital_donor_cells_use_claimant_partnership_and_preserve_marital_statu benunit.loc[benunit["benunit_id"] == 1005, "is_married"] = True marital_before = benunit["is_married"].copy() - result = cohere_uc_capital(frame).frame.table("benunit") + result = cohere_uc_capital(frame, minimum_cell_donors=1).frame.table("benunit") by_id = result.set_index("benunit_id") assert by_id.loc[1007, "frs_benunit_capital"] == 3_000.0 @@ -136,13 +152,16 @@ def test_graph_scoped_capital_redraw_receives_claimant_roles() -> None: tolerances={}, numerics={}, ) - transform = UKUCCapitalCoherenceStageTransform(stage=_stage()) + transform = UKUCCapitalCoherenceStageTransform( + stage=_stage(), minimum_cell_donors=1 + ) result = UKStageKernel("uc_capital_coherence", transform).run(context) capital = result.columns[("benunit", "frs_benunit_capital")] assert capital.loc[1005] == 200.0 assert capital.loc[1007] == 3_000.0 - assert capital.loc[1006] == 888_888.0 # A non-reporter is unchanged. + # The non-reporter draws from base non-reporters, never reporters. + assert capital.loc[1006] in (777_777.0, 999_999.0) assert result.columns[("benunit", "would_claim_uc")].loc[1007] assert ( transform.checkpoint_metadata()["evidence"]["redrawn_spi_reporter_count"] == 2 @@ -161,14 +180,20 @@ def test_transform_is_deterministic_and_idempotent() -> None: pd.testing.assert_frame_equal( first.table(entity), candidate.table(entity), check_exact=True ) - assert transform.checkpoint_metadata()["evidence"] == { + evidence = transform.checkpoint_metadata()["evidence"] + assert {key: evidence[key] for key in evidence if key not in RECEIPTS} == { "stage": "uc_capital_coherence", "post_fill_reporter_count": 5, "redrawn_spi_reporter_count": 2, + "redrawn_spi_benefit_units": 3, "refreshed_would_claim_count": 4, "redraw_seed": UC_CAPITAL_REDRAW_SEED, "redraw_salt": UC_CAPITAL_REDRAW_SALT, + "minimum_cell_donors": UC_CAPITAL_MINIMUM_CELL_DONORS, } + # Two base reporters and two base non-reporters cannot fill a 20-donor + # cell, so every SPI unit draws from its reporter-status pool. + assert evidence["coarsening_levels"][UC_CAPITAL_COARSENING[-1]] == 3 def test_redraw_is_stable_under_input_row_permutation() -> None: @@ -190,20 +215,23 @@ def redraw_tables( ] reporter = benunit_table["benunit_id"].isin(reporter_ids).to_numpy() base = benunit_table[support_channel_column("benunit")].eq("frs").to_numpy() - redraw = ( - benunit_table[support_channel_column("benunit")].eq("spi").to_numpy() - & reporter - ) + redraw = benunit_table[support_channel_column("benunit")].eq("spi").to_numpy() capital = benunit_table["frs_benunit_capital"].to_numpy(dtype=float).copy() - _redraw_spi_reporter_capital( + _redraw_spi_capital( benunit_table, person=person_table, - household=household_table, - household_weights=household_weight_values, + weights=_household_to_benunit_weights( + benunit_table, + person=person_table, + household=household_table, + household_weights=household_weight_values, + ), reporter=reporter, base=base, redraw=redraw, capital=capital, + investment=benunit_financial_investment_income(person_table, benunit_table), + minimum_cell_donors=1, ) return pd.Series(capital, index=benunit_table["benunit_id"]).sort_index() @@ -248,3 +276,78 @@ def test_children_band_caps_at_three_plus_and_boolean_helper_is_strict() -> None _boolean_values(pd.Series([False, True], name="flag")), np.asarray([False, True]), ) + + +def _with_investment_income(frame, income_by_benunit): + person = frame.table("person") + heads = person["is_benunit_head"].astype(bool) + for benunit_id, amount in income_by_benunit.items(): + rows = heads & person["person_benunit_id"].eq(benunit_id) + person.loc[rows, "dividend_income"] = amount + return frame + + +def test_investment_income_bands_follow_the_implied_capital_edges() -> None: + income = np.asarray([0.0, 0.01, 240.0, 240.01, 640.0, 2_000.0, 8_000.0, 9e6]) + np.testing.assert_array_equal( + _investment_income_band(income), [0, 1, 1, 2, 2, 3, 4, 5] + ) + with pytest.raises(ValueError, match="nonnegative"): + _investment_income_band(np.asarray([-1.0])) + + +def test_spi_capital_follows_the_units_own_investment_income() -> None: + # Base reporters 101 and 201 hold 100 and 200 with no investment income; + # give 201 GBP 1,000 of dividends (band 3) and the SPI reporter 1005 the + # same: in exact cells it can only draw 201's capital. + frame = _with_investment_income(_frame(), {201: 1_000.0, 1005: 1_000.0}) + result = cohere_uc_capital(frame, minimum_cell_donors=1) + benunit = result.frame.table("benunit").set_index("benunit_id") + assert benunit.loc[1005, "frs_benunit_capital"] == 200.0 + # Property income is not financial capital's income. + frame = _frame() + frame.table("person")["property_income"] = 50_000.0 + np.testing.assert_array_equal( + benunit_financial_investment_income( + frame.table("person"), frame.table("benunit") + ), + np.zeros(len(frame.table("benunit"))), + ) + + +def test_coarsening_widens_in_the_declared_order_and_keeps_reporter_status() -> None: + # A two-donor floor leaves the 1-child couple reporter cell (one donor) + # short, so 1007 widens; its pool never includes a non-reporter's capital. + result = cohere_uc_capital(_frame(), minimum_cell_donors=2) + benunit = result.frame.table("benunit").set_index("benunit_id") + assert benunit.loc[1007, "frs_benunit_capital"] in (100.0, 200.0, 3_000.0) + assert benunit.loc[1005, "frs_benunit_capital"] in (100.0, 200.0, 3_000.0) + assert benunit.loc[1006, "frs_benunit_capital"] in (777_777.0, 999_999.0) + levels = result.coarsening_levels + assert list(levels) == ["exact_cell", *UC_CAPITAL_COARSENING] + assert sum(levels.values()) == 3 + assert levels["exact_cell"] == 2 # 1005 and 1006 have two donors each + # Without any donor of its reporter status the unit refuses. + frame = _frame() + benunit_table = frame.table("benunit") + benunit_table.loc[ + benunit_table["benunit_id"].isin([401, 501]), "frs_benunit_capital" + ] = -1.0 + with pytest.raises(ValueError, match="reporter status False"): + cohere_uc_capital(frame, minimum_cell_donors=1) + + +def test_receipt_counts_capital_below_what_the_income_implies() -> None: + # 1005 reports GBP 1,000 of dividends (GBP 25,000 at 4%) and holds + # 999,999 before; base 101 holds 100 against GBP 1,000. + frame = _with_investment_income(_frame(), {101: 1_000.0, 1005: 1_000.0}) + result = cohere_uc_capital(frame, minimum_cell_donors=1) + receipt = result.capital_against_investment_income + before = receipt["before"]["implied_above_16000_capital_at_or_below"] + after = receipt["after"]["implied_above_16000_capital_at_or_below"] + assert before["frs"]["benefit_units"] == 1 # 101 is a base row: unchanged + assert after["frs"]["benefit_units"] == 1 + assert before["spi"]["benefit_units"] == 0 + # 1005 now draws from its income band's donor, 101 (GBP 100). + assert after["spi"]["benefit_units"] == 1 + assert receipt["after"]["spi_reporters_capital_above_16000"] == 0 diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_was_lisa.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_was_lisa.py index 9d554cd21..0e097eceb 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_was_lisa.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_was_lisa.py @@ -245,6 +245,8 @@ def _recipient_frame(households: int = 64): "self_employment_income": 0.0, "private_pension_income": 0.0, "capital_income": 0.0, + "property_income": 0.0, + "is_uc_claimant": adult, } ) person_id += 1 @@ -263,6 +265,7 @@ def _recipient_frame(households: int = 64): "region": "LONDON" if household % 2 else "WALES", "num_bedrooms": 1 + household % 4, "council_tax": 1_000.0 + 10.0 * household, + "council_tax_rebate": 0.0, "household_net_income": 20_000.0 + 1_000.0 * (household % 60), "is_renting": bool(household % 4 == 0), "tenure_type": tenures[household % 4], diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_was_wealth.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_was_wealth.py index 849582d80..2f9d69f74 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_was_wealth.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_was_wealth.py @@ -14,6 +14,7 @@ UK_WAS_DERIVED_TOTALS, UK_WAS_DRAWN_ONLY_COLUMNS, UK_WAS_ENGINE_PREDICTOR_ENTITIES, + UK_WAS_ENGINE_PREDICTORS, UK_WAS_NET_FINANCIAL_LIABILITIES, UK_WAS_STRATIFIED_TARGETS, UK_WAS_TENURE_CATEGORY_COLUMN, @@ -41,6 +42,7 @@ def _chain_operation(n_estimators: int = 2) -> dict[str, object]: "kind": "fit_weighted_qrf_chain", "seed": 0, "n_estimators": n_estimators, + "predictors": list(UK_WAS_WEALTH_PREDICTORS), "stratified_targets": { target: list(categories) for target, categories in UK_WAS_STRATIFIED_TARGETS.items() @@ -58,6 +60,14 @@ def _chain_operation(n_estimators: int = 2) -> dict[str, object]: } +def _materialize_operation() -> dict[str, object]: + return { + "kind": "materialize_rules_engine_predictors", + "predictors": list(UK_WAS_ENGINE_PREDICTORS), + "consumed_only": True, + } + + class _FakeEngine: """Returns engine variables at their native entity, like the real adapter.""" @@ -87,7 +97,7 @@ def _stage() -> SourceStageSpec: "source": "test", "grain": "household", "artifacts": [], - "operations": [_chain_operation()], + "operations": [_materialize_operation(), _chain_operation()], "outputs": list(UK_WAS_WEALTH_OUTPUT_COLUMNS), "nonnegative_outputs": [ name @@ -116,7 +126,7 @@ def _raw_was() -> pd.DataFrame: "totalpenr8_aggr": [100.0, 200.0], "dvvaldbt_scaper8_aggr": [40.0, 50.0], "NumAdultR8": [2, 1], - "NumCh18R8": [1, 0], + "NumChildR8": [1, 0], "DVGIPPENR8_AGGR": [11.0, 12.0], "DVGISER8_AGGR": [13.0, 14.0], "DVGIINVR8_aggr": [15.0, 16.0], @@ -124,7 +134,8 @@ def _raw_was() -> pd.DataFrame: "HBedRmR8": [3, 4], "GORR8": [8, 12], "DVPriRntR8": [-9, 2], - "CTAmtR8": [1000.0, 1200.0], + "DVCTaxAmtAnnualR8": [1000.0, 1200.0], + "DVNetRentAmtAnnualR8_aggr": [0.0, 300.0], "HFINWNTR8_Sum": [-4_480.0, -1_356.0], "HFINWNTR8_exSLC_Sum": [520.0, 644.0], "HFINWR8_SUM": [530.0, 644.0], @@ -134,6 +145,7 @@ def _raw_was() -> pd.DataFrame: "Ten1R8": [2, 4], "DVhvalueR8": [100_000.0, 0.0], "DVHseValR8_sum": [1000.0, 2000.0], + "DVBltValR8_sum": [0.0, 300.0], "DVBlDValR8_sum": [3000.0, 4000.0], "DVTotinc_bhcR8": [50000.0, 60000.0], "DVSaValR8_aggr": [500.0, 600.0], @@ -164,6 +176,9 @@ def _frame() -> object: "employment_income": [4.0, 6.0, 12.0, 8.0], "self_employment_income": [0.0, 0.0, 1.0, 0.0], "capital_income": [1.0, 2.0, 4.0, 0.0], + "property_income": [0.0, 100.0, 50.0, 0.0], + # The 19-year-old is a dependent child of the benefit unit. + "is_uc_claimant": [True, True, False, True], } ) benunit = pd.DataFrame( @@ -180,6 +195,7 @@ def _frame() -> object: "region": ["NORTHERN_IRELAND", "SCOTLAND"], "num_bedrooms": [3, 4], "council_tax": [1000.0, 1200.0], + "council_tax_rebate": [250.0, 0.0], "household_net_income": [50000.0, 60000.0], "tenure_type": ["OWNED_WITH_MORTGAGE", "OWNED_OUTRIGHT"], } @@ -213,7 +229,10 @@ def test_was_donor_cleaning_arithmetic_and_exact_case_insensitive_columns() -> N assert donor["tenure_social_rent"].tolist() == [False, True] assert donor["tenure_private_rent"].tolist() == [False, False] # The remainders that make each total the sum of its drawn components. - assert donor["other_property_value"].tolist() == [90.0, 400.0] + # Buy-to-let joins the other houses in other residential property, so + # the undrawn remainder shrinks by it (microcosm#1095). + assert donor["other_residential_property_value"].tolist() == [1000.0, 2300.0] + assert donor["other_property_value"].tolist() == [90.0, 100.0] assert donor["other_financial_assets"].tolist() == [5.0, 14.0] assert donor["main_residence_mortgage"].tolist() == [1000.0, 0.0] assert donor["other_mortgage"].tolist() == [0.0, 0.0] @@ -321,9 +340,15 @@ def test_recipient_predictors_sum_person_and_benunit_variables_to_household() -> assert predictors["private_pension_income"].tolist() == [1.0, 2.0] assert predictors["self_employment_income"].tolist() == [0.0, 1.0] assert predictors["capital_income"].tolist() == [3.0, 4.0] - assert predictors["num_adults"].tolist() == [2.0, 2.0] - assert predictors["num_children"].tolist() == [0.0, 0.0] + # Adults and children are the FRS family roles, as WAS counts them, so + # the 19-year-old dependant is a child (microcosm#1095). + assert predictors["num_adults"].tolist() == [2.0, 1.0] + assert predictors["num_children"].tolist() == [0.0, 1.0] + assert predictors["rental_income"].tolist() == [100.0, 50.0] assert predictors["household_net_income"].tolist() == [50000.0, 60000.0] + # The donor records the bill paid, so the reduction comes off the + # liability before council tax reduction (microcosm#1095). + assert predictors["council_tax"].tolist() == [750.0, 1200.0] assert predictors[UK_WAS_TENURE_CATEGORY_COLUMN].tolist() == [ "owned_with_mortgage", "owned_outright", @@ -699,7 +724,7 @@ def test_chain_declaration_drift_is_refused() -> None: "source": "test", "grain": "household", "artifacts": [], - "operations": [operation], + "operations": [_materialize_operation(), operation], "outputs": list(UK_WAS_WEALTH_OUTPUT_COLUMNS), } ) @@ -715,12 +740,29 @@ def test_chain_declaration_drift_is_refused() -> None: "source": "test", "grain": "household", "artifacts": [], - "operations": [operation], + "operations": [_materialize_operation(), operation], "outputs": list(UK_WAS_WEALTH_OUTPUT_COLUMNS), } ) with pytest.raises(ValueError, match="derived_totals drifted"): module._assert_chain_declaration(stage) + operation = _chain_operation() + operation["predictors"] = [ + name for name in UK_WAS_WEALTH_PREDICTORS if name != "rental_income" + ] + stage = SourceStageSpec.from_mapping( + { + "stage": "was_wealth", + "survey": "test", + "source": "test", + "grain": "household", + "artifacts": [], + "operations": [_materialize_operation(), operation], + "outputs": list(UK_WAS_WEALTH_OUTPUT_COLUMNS), + } + ) + with pytest.raises(ValueError, match="predictors drifted"): + module._assert_chain_declaration(stage) def test_private_pension_wealth_split_preserves_the_old_corporate_wealth_identity() -> ( @@ -791,6 +833,7 @@ def _synthetic_recipients(n: int = 80, seed: int = 1063) -> pd.DataFrame: "employment_income": rng.uniform(0, 60_000, n), "self_employment_income": rng.uniform(0, 10_000, n), "capital_income": rng.uniform(0, 5_000, n), + "rental_income": np.where(rng.uniform(size=n) < 0.1, 8_000.0, 0.0), "num_bedrooms": rng.integers(1, 6, n), "council_tax": rng.uniform(800, 3_000, n), } diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_wealth_resources.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_wealth_resources.py index 5f27278bc..5aaa48144 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_wealth_resources.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_wealth_resources.py @@ -118,7 +118,7 @@ def test_support_bounds_tool_rounds_synthetic_donor_outward(tmp_path: Path) -> N "totalpenr8_aggr": [100, 200], "dvvaldbt_scaper8_aggr": [40, 50], "NumAdultR8": [2, 1], - "NumCh18R8": [1, 0], + "NumChildR8": [1, 0], "DVGIPPENR8_AGGR": [11, 12], "DVGISER8_AGGR": [13, 14], "DVGIINVR8_aggr": [15, 16], @@ -126,7 +126,8 @@ def test_support_bounds_tool_rounds_synthetic_donor_outward(tmp_path: Path) -> N "HBedRmR8": [3, 4], "GORR8": [8, 12], "DVPriRntR8": [-9, 2], - "CTAmtR8": [1000, 1200], + "DVCTaxAmtAnnualR8": [1000, 1200], + "DVNetRentAmtAnnualR8_aggr": [0, 300], "HFINWNTR8_Sum": [-4480, -1356], "HFINWNTR8_exSLC_Sum": [520, 644], "HFINWR8_SUM": [530, 644], @@ -136,6 +137,7 @@ def test_support_bounds_tool_rounds_synthetic_donor_outward(tmp_path: Path) -> N "Ten1R8": [2, 4], "DVhvalueR8": [100000, 0], "DVHseValR8_sum": [1000, 2000], + "DVBltValR8_sum": [0, 300], "DVBlDValR8_sum": [3000, 4000], "DVTotinc_bhcR8": [50000, 60000], "DVSaValR8_aggr": [500, 600], diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_weighted_integrity.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_weighted_integrity.py index 49b860dce..58b8028c8 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_weighted_integrity.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_weighted_integrity.py @@ -670,13 +670,13 @@ def test_committed_exclusion_registers_load() -> None: # is retired. The 3 October final build's certifier earned three more, # signed 2026-10-04: the FRS access-fund outlier at the weight bound # (expiring with the owed period rule) and the SPI channel's two - # legacy-benefit leaves. - assert set(input_mass["efrs-post-calibration"]) == { - "access_fund", - "dfe_education_spending", - "jsa_income_reported", - "working_tax_credit_reported", - } + # legacy-benefit leaves. All three are retired with the microcosm#1095 + # ports: spi_benefit_coherence zeroes income-based JSA and Working Tax + # Credit on SPI rows, and on the review-head arm the columns sit at +316% + # and +103% of the reference and the access fund at +62%, its household + # off the weight bound, all inside the fence, so the gate fails them as + # stale. + assert set(input_mass["efrs-post-calibration"]) == {"dfe_education_spending"} assert set(qrf_tail) == {"charitable_investment_gifts"} for record in (*input_mass["efrs-post-calibration"].values(), *qrf_tail.values()): assert record.approved_by == "juaristi22" diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 2f9a3775b..8e505e9a2 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -416,13 +416,13 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: # fingerprint derives from the manifest digest. Editing the spec moves all # three here in the same reviewed change. _UK_GATE_BATTERY_POLICY_SHA256 = ( - "82a92dfa7ba4e4ce81cfd44d7b89737cf3cce50d69fd2d6bbeeae0ca15a0f8d5" + "6e1a3a38efe1e984426d4a40a63f1671434d27c44e89d75abd7290a955af18b0" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c117864fac6df5bb7f37f466c068b8dd9dd032b694cf3d521c51b5dca71b5865" + "f0c8e1d4f3e97ff6fd6ff51dff9db6414816785807cec30a5ea9526630af6a65" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "7ff71ed911b840c01a1b6395de37a04fdf95498444bd692b32d89f3b1767a128" + "c361fe49d7edd364f31a1f30282fe5b9050e779d311ab438ab4aef7e3e95148c" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -487,6 +487,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "stage_health", "transferred", ), + "uk_stage_spi_benefit_coherence": ("stage_health", "transferred"), "uk_stage_pension_credit_take_up": ("stage_health", "transferred"), "uk_stage_child_benefit_take_up": ("stage_health", "transferred"), "uk_stage_cgt_incidence_clone_mass": ("stage_health", "transferred"), @@ -585,6 +586,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", + "uk_stage_spi_benefit_coherence", "uk_stage_pension_credit_take_up", "uk_stage_child_benefit_take_up", "uk_stage_cgt_incidence_clone_mass", @@ -606,7 +608,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: # canonical hash; this pins the wrapped digest so the entry's evidence line # still binds the enhanced-FRS incumbent totals. _UK_GATE_BATTERY_INPUT_MASS_EVIDENCE_SHA256 = ( - "8829fb83db6a16482be80cbe1b1da125608448b5a34b9cbb0561aac32a870447" + "d28a1fd613d61a21b06c6fccc3e3c95c0dd0173b0957c85bc4618170cac0907f" ) # The degenerate binding's evidence payload digests the resolved exclusion # records; for a release that must be the committed register, so its digest @@ -801,6 +803,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: "uk_stage_nts_bus_travel_support", "uk_stage_pension_credit_take_up", "uk_stage_salary_sacrifice_realization", + "uk_stage_spi_benefit_coherence", "uk_stage_spi_support_channel_mass", "uk_stage_student_loans_realization", "uk_stage_uc_deduction_attributes", @@ -848,10 +851,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: _UK_CERTIFICATION_PART_DIGESTS: Mapping[str, Mapping[str, str]] = { "spine": { "gates_manifest_sha256": ( - "9708ee040b34e8dbecdb88691079f00682ccf9ca20599f07342b4c33c2e56f40" + "da12b5be6236783cb7af79279175116548d7c99da283e4e45ef40b3ba3cd3168" ), "policy_sha256": ( - "b22f79584c16ab81fbfa131c19c16f5bc5c1e484003c73a695abf3446ff6175b" + "447841b7d7e57abf7e64574884b6b3db15ee44f4be09e4863cda066f0005e498" ), }, "calibration_seam": { @@ -864,7 +867,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: }, "release_cut": { "gates_manifest_sha256": ( - "4eed0ed4dc6785f7f4611e9af96a84594e73806eccc6eaf6b76f85630b378f35" + "e072281905223b9346f77da11dd52c390421b22046292cef92094a3b894ab365" ), "policy_sha256": ( "a673ec3efe1be53567ddc12b344e44ab872e05a6ebcea2862b1762952901ce78" diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index 7412ea5e5..288b0a72a 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -92,13 +92,6 @@ # The committed per-reference register (microcosm#1063 c9): the policy payloads # sealed into the input-mass evidence digest. UK_INPUT_MASS_REVIEWED_EXCLUSIONS: dict[str, dict[str, str]] = { - "access_fund": { - "reason": "One FRS household carries 98% of the candidate's access-fund mass (GBP 1.01bn against the incumbent's GBP 160m, +535%): sernum 14443's 19-year-old reports an access fund of GBP 4,500 with FRS period code 5 (calendar month), which the FRS weeklyises to GBP 1,035.62 (ACCSSAMT) and the spine annualises to GBP 54,037, eleven times the next largest FRS value; the calibration takes the household and its two capital-gains copies to the 10x weight bound. The value is almost certainly an annual or termly award under the wrong period code; the input stays on the release surface until the period rule is settled in the spine, and the exclusion expires with it.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-01-04", - }, "dfe_education_spending": { "reason": "The candidate carries DfE education spending through the build (GBP 98.8bn against the incumbent's GBP 52.8m, +187,061%): the enhanced-FRS reference carries almost none of this input, so the comparison measures the reference's omission, not the candidate's. The input stays on the release surface and in the coverage manifest.", "approved_by": "juaristi22", @@ -106,20 +99,6 @@ "approved_on": "2026-10-02", "expires_on": "2027-04-02", }, - "jsa_income_reported": { - "reason": "The candidate carries GBP 272m of reported income-based JSA against the incumbent's GBP 23m (+1,058%): the enhanced-FRS reference holds only the FRS respondents' amounts, while the spine's SPI synthetic channel receives this legacy-benefit leaf from the stage-2 QRF at FRS rates (76 of the 196 nonzero rows and most of the mass) and a few rows sit at the calibration's weight bound. Neither is new to this build: the 2026-09-30 main candidate stood at +428% on the same column. The comparison measures the SPI channel's imputation of a legacy benefit, which is a design question for the channel, not a mass the candidate lost or invented.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-04-04", - }, - "working_tax_credit_reported": { - "reason": "The candidate carries GBP 625m of reported Working Tax Credit against the incumbent's GBP 74m (+747%): the enhanced-FRS reference holds only the FRS respondents' amounts, while the spine's SPI synthetic channel receives this legacy-benefit leaf from the stage-2 QRF at FRS rates (274 of the 372 nonzero rows) and a few rows sit at the calibration's weight bound. The 2026-09-30 main candidate stood at +421% on the same column. Tax credits closed in April 2025, so the SPI channel's treatment of the leaf is a design question for the channel, not a mass the candidate lost or invented.", - "approved_by": "juaristi22", - "adjudication": "microcosm#1063 (PR #1089 release-cut certifier on the 2026-10-03 final build; ruling 2026-10-04 in session: the deferrals needed to build and publish the national dataset are signed, each with its diagnosis)", - "approved_on": "2026-10-04", - "expires_on": "2027-04-04", - }, } GIT_COMMIT = "5fa48f07436a806ad75ff76fd22cfb8613bddbe0" DATASET_SHA = "d" * 64 @@ -148,19 +127,19 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: UK_GATE_BATTERY_PRODUCER = "microcosm.build.gate_battery" UK_GATE_BATTERY_SIGNING_KEY_ENV = "MICROCOSM_UK_TERMINAL_GATE_SIGNING_KEY" UK_GATE_BATTERY_POLICY_SHA256 = ( - "82a92dfa7ba4e4ce81cfd44d7b89737cf3cce50d69fd2d6bbeeae0ca15a0f8d5" + "6e1a3a38efe1e984426d4a40a63f1671434d27c44e89d75abd7290a955af18b0" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c117864fac6df5bb7f37f466c068b8dd9dd032b694cf3d521c51b5dca71b5865" + "f0c8e1d4f3e97ff6fd6ff51dff9db6414816785807cec30a5ea9526630af6a65" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "7ff71ed911b840c01a1b6395de37a04fdf95498444bd692b32d89f3b1767a128" + "c361fe49d7edd364f31a1f30282fe5b9050e779d311ab438ab4aef7e3e95148c" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "6f0243bcda09dad26945376230c44ec3cf55d4e417c3a25e29bae8c59bc1a69d" ) UK_GATE_BATTERY_INPUT_MASS_EVIDENCE_SHA256 = ( - "8829fb83db6a16482be80cbe1b1da125608448b5a34b9cbb0561aac32a870447" + "d28a1fd613d61a21b06c6fccc3e3c95c0dd0173b0957c85bc4618170cac0907f" ) #: Spec entry id -> (neutral gate name, phase, legacy detail-schema name). UK_GATE_BATTERY_ENTRIES = { @@ -211,6 +190,7 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "transferred", None, ), + "uk_stage_spi_benefit_coherence": ("stage_health", "transferred", None), "uk_stage_pension_credit_take_up": ("stage_health", "transferred", None), "uk_stage_child_benefit_take_up": ("stage_health", "transferred", None), "uk_stage_cgt_support_split_mass": ( @@ -1268,6 +1248,7 @@ def _gate_battery_payload( "frs_hmrc_spine_leaves", "spi_support_channel", "hmrc_spi_income_spine", + "spi_benefit_coherence", "uc_capital_coherence", "pension_credit_take_up", "child_benefit_take_up", @@ -1296,6 +1277,7 @@ def _gate_battery_payload( "uk_stage_frs_hmrc_spine_leaves_signal": "frs_hmrc_spine_leaves", "uk_stage_spi_support_channel_mass": "spi_support_channel", "uk_stage_hmrc_spi_income_spine_identity": "hmrc_spi_income_spine", + "uk_stage_spi_benefit_coherence": "spi_benefit_coherence", "uk_stage_pension_credit_take_up": "pension_credit_take_up", "uk_stage_child_benefit_take_up": "child_benefit_take_up", "uk_stage_cgt_support_split_mass": "cgt_support_split", diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/cgt_asset_type_facts.json b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/cgt_asset_type_facts.json index 8655dd6e6..d256e0964 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/cgt_asset_type_facts.json +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/cgt_asset_type_facts.json @@ -2,70 +2,70 @@ "resource": "synthetic-cgt-asset-type.json", "resource_sha256": "synthetic", "source_commit": "synthetic", - "table4_all_gains": 6803877.8232513005, + "table4_all_gains": 6972908.147064025, "table4_all_tax": 0.0, - "table4_all_taxpayers": 16.094983343942488, + "table4_all_taxpayers": 16.094983343942484, "table4_bands": [ { - "gains": 8469.81629743428, + "gains": 8217.473099943845, "lower_bound": 0, "tax": null, - "taxpayers": 2.0315589349981042, + "taxpayers": 1.9497297868684291, "upper_bound": 10000 }, { - "gains": 21793.660633989297, + "gains": 21896.094502214266, "lower_bound": 10000, "tax": null, - "taxpayers": 1.4192719822325444, + "taxpayers": 1.4186023480467669, "upper_bound": 25000 }, { - "gains": 41822.32276068652, + "gains": 34127.177490619295, "lower_bound": 25000, "tax": null, - "taxpayers": 1.1984100692769308, + "taxpayers": 0.9765810909271515, "upper_bound": 50000 }, { - "gains": 98900.8658246953, + "gains": 100905.8426857189, "lower_bound": 50000, "tax": null, - "taxpayers": 1.3284701286752632, + "taxpayers": 1.356529326242432, "upper_bound": 100000 }, { - "gains": 315094.2653986191, + "gains": 380501.42456169357, "lower_bound": 100000, "tax": null, - "taxpayers": 2.0148156202095766, + "taxpayers": 2.436294781706467, "upper_bound": 250000 }, { - "gains": 853577.3892905796, + "gains": 716332.7001442233, "lower_bound": 250000, "tax": null, - "taxpayers": 2.300508382822492, + "taxpayers": 1.8749877551853813, "upper_bound": 500000 }, { - "gains": 985119.1545275399, + "gains": 1133930.764634916, "lower_bound": 500000, "tax": null, - "taxpayers": 1.3228478772098182, + "taxpayers": 1.5052615850211621, "upper_bound": 1000000 }, { - "gains": 4479100.348517757, + "gains": 4576996.669944695, "lower_bound": 1000000, "tax": null, - "taxpayers": 4.479100348517757, + "taxpayers": 4.576996669944696, "upper_bound": null } ], - "table4_individuals_gains": 6803877.8232513005, + "table4_individuals_gains": 6972908.147064025, "table4_individuals_tax": 0.0, - "table4_individuals_taxpayers": 16.094983343942488, + "table4_individuals_taxpayers": 16.094983343942484, "table4_trusts_gains": 0.0, "table4_trusts_tax": 0.0, "table7_total_disposals": 2743095.2380952383, @@ -115,11 +115,11 @@ } ], "table8a_disposals_total": 30.35054002000583, - "table8a_gains_total": 36521680.19444137, - "table8a_tax_total": 7304336.038888275, + "table8a_gains_total": 39631315.700302444, + "table8a_tax_total": 7926263.140060489, "table8a_taxpayers_total": 27.591400018187116, - "table8b_all_gains": 36521680.19444137, + "table8b_all_gains": 39631315.700302444, "table8b_all_taxpayers": 27.591400018187116, - "table8b_individuals_gains": 36521680.19444137, + "table8b_individuals_gains": 39631315.700302444, "table8b_individuals_taxpayers": 27.591400018187116 } diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/fixture.json b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/fixture.json index 7e28c5a62..a47c1b7af 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/fixture.json +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/fixture.json @@ -559,7 +559,7 @@ "nhs_admitted_patient_spending", "nhs_outpatient_spending" ], - "notes": "Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine's CPI index, rail support by ORR table 7270's own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame's journeys (microcosm#930; the", + "notes": "Ports ETB public-services QRF at household grain, uprates the FYE-2024 donor to the FRS 2024-25 base year by the declared uprate_donor_columns step (education by the engine's CPI index, rail support by ORR table 7270's own FY2024-25 over FY2023-24 outturn, bus support by DfT BUS05bi England net support, a factor the pricing overrides outside Wales and Northern Ireland and which therefore only positions the donor before the QRF), prices bus support from the frame's journeys (microcosm#930; the #890 rake to the published net support retired on Mar\u00eda's ruling of 2026-09-23): per household, the published concessionary travel reimbursement per concessionary boarding times its eligible persons' boardings plus the rest of the published net support per boarding times every boarding, boardings being the nts_bus_travel trips times the fare pricing's boardings per resident trip, for London and England outside London (DfT BUS05bi and BUS01) and Scotland (Scottish Transport Statistics components and journeys); Wales (no published boardings) and Northern Ireland (the NITHC accounts carry bus and rail jointly) keep the chain's raw draw, clipped to donor support; the published totals stay bound as calibration targets and now measure the priced quantity, computes rail_usage from the 2024 fare index, and allocates NHS visits/spending to persons using the signed half-open age bands with the donor table's native 85-89, 90-94 and 95+ top bands (the former 85+ fold-in was retired once age_tail moved ahead of this stage and recipients could populate those bands). The year-max donor filter resolves to 2023 on the pinned tab (the file labels financial year ending 2024 as year 2023), so the services training year coincides with the VAT training year and the fare-index year - the incumbent's apparent three-way year mismatch is vacuous on this vintage. The recipient is_adult and is_child counts are the household's FRS claimants and partners and its other members (is_uc_claimant), as the donor's adults and childs count adults and dependent children, not the engine's age-18 split (uk-data#486, microcosm#1095).", "operations": [ { "annualization_weeks": 52, @@ -597,12 +597,12 @@ "derived_predictors": { "count_further_education": "current_education in (UPPER_SECONDARY, TERTIARY)", "count_primary_education": "current_education == PRIMARY", - "count_secondary_education": "current_education == LOWER_SECONDARY" + "count_secondary_education": "current_education == LOWER_SECONDARY", + "is_adult": "count of household members with is_uc_claimant (FRS claimants and partners)", + "is_child": "count of household members without is_uc_claimant (dependent children)" }, "kind": "materialize_rules_engine_predictors", "predictors": [ - "is_adult", - "is_child", "is_SP_age", "dla", "pip", @@ -936,7 +936,7 @@ ], "grain": "household", "nonnegative_outputs": [], - "notes": "Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth.", + "notes": "Ports ETB VAT imputation using the 2023 donor year and cited VAT anchors; missing or NaN rates fail loud rather than falling back. The donor-realized support includes negative rates (4 of 4,199 cleaned 2023 donor rows, minimum -3.4: totvat can exceed expdis in the raw ETB accounts), so the output is deliberately absent from nonnegative_outputs and the support gate is the guard - the net_financial_wealth precedent from was_wealth. The recipient is_adult and is_child counts are the household's FRS claimants and partners and its other members (is_uc_claimant), as the donor's adults and childs count adults and dependent children, not the engine's age-18 split (uk-data#486, microcosm#1095).", "operations": [ { "annualization_weeks": 52, @@ -947,10 +947,12 @@ "year": 2023 }, { + "derived_predictors": { + "is_adult": "count of household members with is_uc_claimant (FRS claimants and partners)", + "is_child": "count of household members without is_uc_claimant (dependent children)" + }, "kind": "materialize_rules_engine_predictors", "predictors": [ - "is_adult", - "is_child", "is_SP_age", "household_net_income" ] @@ -1040,8 +1042,8 @@ "locator": "househol.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "c56d5f75ee60027e6ff74f54889f6880ade9f6deb0bace0f27d21f8e5976c6a1", - "size_bytes": 15173, + "sha256": "d6c1b0f31e20980c3effb033fba5ba76527788c750e0051b0176e3bcb29bc89d", + "size_bytes": 15915, "table": "househol", "vintage": "synthetic-h2" } @@ -1050,7 +1052,7 @@ "nonnegative_outputs": [ "council_tax" ], - "notes": "Re-reads raw househol.tab because spine council_tax_reported clips missing values. Scottish Water charges are netted before cell means; no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped.", + "notes": "Re-reads raw househol.tab because spine council_tax_reported clips missing values. FRS 2024-25 CTANNUAL is the bill after discounts and council tax reduction, and the engine reads council_tax before the reduction, so a household reporting a reduction gets its CTREBAMT added back and the cells pool non-recipients only (uk-data#496/#499, microcosm#1095). Scottish water and sewerage charges are netted before cell means at the shares DWP's CTANNUAL carries (the gross charges in full for non-recipients, 65% for reduction recipients); no-donor cells impute zero. The dead ct_mean.replace(-1, ...) branch is intentionally dropped.", "operations": [ { "delimiter": "\t", @@ -1066,10 +1068,10 @@ "ctband", "adulth == 1" ], - "donor_filter": "raw ctannual > 0", + "donor_filter": "raw ctreb != 1 and ctannual > 0", "kind": "impute_cell_means", "missing": "raw ctannual < 0 or NaN", - "value": "Scottish-water-netted CTANNUAL" + "value": "council tax before council tax reduction: CTANNUAL net of the Scottish water and sewerage charges ((CWATAMT1 + CSEWAMT1) x 365.25/7, at 0.65 where CTREB is 1; CWATAMTD where CWATAMT1 is not positive), plus CTREBAMT x 365.25/7 where CTREB is 1 and CTREBAMT > 0; a CTREB 1 household without a positive CTREBAMT takes the larger of its netted CTANNUAL and its cell mean" } ], "outputs": [ @@ -1630,8 +1632,8 @@ "locator": "househol.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "c56d5f75ee60027e6ff74f54889f6880ade9f6deb0bace0f27d21f8e5976c6a1", - "size_bytes": 15173, + "sha256": "d6c1b0f31e20980c3effb033fba5ba76527788c750e0051b0176e3bcb29bc89d", + "size_bytes": 15915, "table": "househol", "vintage": "synthetic-h2" } @@ -1899,8 +1901,8 @@ "locator": "househol.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "c56d5f75ee60027e6ff74f54889f6880ade9f6deb0bace0f27d21f8e5976c6a1", - "size_bytes": 15173, + "sha256": "d6c1b0f31e20980c3effb033fba5ba76527788c750e0051b0176e3bcb29bc89d", + "size_bytes": 15915, "table": "househol", "vintage": "synthetic-h2" }, @@ -2022,11 +2024,11 @@ }, { "kind": "map_columns", - "scope": "raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence)" + "scope": "raw-to-column E2 mappings and FRS claimant-role derivation (is_benunit_head OR is_parent OR no dependent children within the benefit unit) to is_uc_claimant; benunit.TOTCAPB4 -> frs_benunit_capital with blank, nonnumeric, or negative raw values -> named -1 unavailable sentinel (mapped-row count reported in stage evidence); Scottish water_and_sewerage_charges is the charge paid, (CWATAMT1 + CSEWAMT1) less the CTDISC/CT25D50D status discount, or where CTREB is 1 less the larger of that discount and the Water Charges Reduction Scheme's 35% (the full-reduction case), and CWATAMTD where CWATAMT1 is not positive (uk-data#499, microcosm#1095)" }, { "kind": "map_coded_amounts", - "scope": "region, tenure, accommodation, council tax band, benefit-code amount mappings; adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance" + "scope": "region, tenure, accommodation, council tax band, benefit-code amount mappings (Scotland's Adult and Child Disability Payment codes 117/118 and 121/122 into the PIP and DLA columns they replace; benefit recovery codes 69 and 70 unmapped); adult HOURTOT care-hours band code to weekly care_hours at the band's lower edge (codes 5, 6, 7 and 10 reach the 35-hour Carer's Allowance line); would_claim_carers_allowance from positive reported Carer's Allowance" }, { "kind": "annualize_periodic_amounts", @@ -2671,7 +2673,7 @@ "hmrc_spi_total_investment_income", "hmrc_spi_assessable_income" ], - "notes": "Runs the SPI-trained income QRFs on the raw-spine support channel, initializes FRS charity columns to zero, trains FRS-only stage 2 before redrawing base-channel dividends, and emits a sidecar-only 208-fact replay report for the spine path.", + "notes": "Runs the SPI-trained income QRFs on the raw-spine support channel, drawing for its claimants and partners aged 16 and over so dependants aged 16 to 19 keep their FRS twin's values (uk-data#504, microcosm#1095), initializes FRS charity columns to zero, trains FRS-only stage 2 on the FRS rows' reported values, leaves every FRS-channel income as reported (no base-channel redraw of dividends; uk-data#498, microcosm#1095), and emits a sidecar-only 208-fact replay report for the spine path.", "operations": [ { "artifact_roles": [ @@ -2809,6 +2811,7 @@ ], "rebase_income_to_build_period": true, "recipient_minimum_age": 16, + "recipient_role_column": "is_uc_claimant", "require_all_outputs": true, "require_all_predictors": true, "sample_size": 64, @@ -3009,7 +3012,7 @@ "other_investment_income": "This remains a stage-1 SPI draw and an official HMRC fact component, but it is not an FRS-only stage-2 predictor: the incumbent UK data build's frs_only.py defines exactly six income predictors and the certified Microcosm UK base candidate has no other_investment_income column." }, "seed": 43, - "target_population": "spi_synthetic_support_channel", + "target_population": "spi_synthetic_support_channel claimants and partners (is_uc_claimant) aged 16 and over", "training_population": "uk_frs_raw_spine_base_support_channel", "weight": "household_weight", "weight_mapping": "household_to_person" @@ -3028,14 +3031,6 @@ "spi_state_pension_leaf": "hmrc_spi_state_pension_income", "state_pension_age": "policyengine-uk gov.dwp.state_pension.age at the build instant" }, - { - "columns": [ - "dividend_income" - ], - "fit": "stage1", - "kind": "redraw_columns_from_fitted_qrf", - "rows": "base_support_channel" - }, { "amount_unit_multiplier": 1000000, "artifact_role": "published_fact_surface", @@ -4513,6 +4508,97 @@ "stage": "salary_sacrifice", "survey": "Family Resources Survey 2024-25 salary-sacrifice respondents and HMRC salary-sacrifice reform analysis" }, + "spi_benefit_coherence": { + "artifacts": [], + "grain": "person+benunit", + "nonnegative_outputs": [], + "notes": "Runs on SPI-channel rows after uc_reporter_redraw, the last writer of Universal Credit reports, and before uc_capital_coherence and the Pension Credit and Child Benefit take-up stages (microcosm#1095, uk-data#514). The stage-2 forests of hmrc_spi_income_spine re-impute each SPI adult's benefit reports from age, gender, region and the new incomes, with nothing of the benefit unit's entitlement or claim history. This stage zeroes the SPI rows' contributory and income-based JSA, income-related ESA, Income Support, Working and Child Tax Credit, Severe Disablement Allowance and Sure Start Maternity Grant reports, whose award needs an existing legacy claim, an out-of-work test, or a claim the copied household's new incomes cannot carry (policyengine-uk pays income-related ESA as reported behind a capital test alone); restores Industrial Injuries Disablement Benefit, the Armed Forces Compensation Scheme and bereavement support from the FRS twin (person_source_id), since they follow an injury, service or a death; re-derives the disability flags (the categories, which read only AA, DLA and PIP, are asserted unchanged) and receives_benefits_in_own_right from the final reports; and redraws would_claim_uc for SPI benefit units as frs_take_up draws it for FRS units: a unit with a Universal Credit reporter claims, and the other units in the Universal Credit age population claim as the residual of the contract's universal_credit rate on draws keyed on the SPI unit's own identity. Contributory ESA, PIP, DLA, AA, Carer's Allowance, State Pension and Winter Fuel Payment keep their draws, and FRS rows are never modified; contributory ESA is open to new claims and not income-tested, and the incapacity it needs follows the person, whose health and disability reports the SPI copy keeps.", + "operations": [ + { + "columns": [ + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported" + ], + "kind": "zero_spi_channel_reports", + "reason": "award needs an existing legacy claim, an out-of-work test, or a claim the copied household's new incomes cannot carry", + "rows": "spi_synthetic_support_channel" + }, + { + "columns": [ + "iidb_reported", + "afcs_reported", + "bsp_reported" + ], + "kind": "restore_spi_channel_reports_from_source", + "linkage": "person_source_id -> FRS-channel person_id", + "reason": "follows an injury, service or a death, not income", + "rows": "spi_synthetic_support_channel" + }, + { + "kind": "derive", + "scope": "disability categories and flags re-derived on SPI-channel rows from the final reports with the frs_disability rule at its declared year; the categories, which read only AA, DLA and PIP, asserted unchanged" + }, + { + "formula": "universal_credit_reported + jsa_contrib_reported + jsa_income_reported + esa_contrib_reported + esa_income_reported > 0 (frs_education), SPI-channel rows; FRS rows asserted unchanged", + "kind": "derive", + "output": "receives_benefits_in_own_right" + }, + { + "aggregates": { + "universal_credit_reported_anchor": "universal_credit_reported" + }, + "consumed_only": true, + "kind": "aggregate_person_to_benunit", + "method": "any_positive" + }, + { + "aggregates": { + "uc_age_eligible": "age" + }, + "consumed_only": true, + "kind": "aggregate_person_to_benunit", + "method": "any_adult_under_state_pension_age" + }, + { + "anchor": "universal_credit_reported_anchor", + "draw": "would_claim_uc", + "kind": "assign_binary_with_anchored_residual", + "output": "would_claim_uc", + "population": "uc_age_eligible", + "rate_key": "universal_credit", + "rows": "spi_synthetic_support_channel", + "seed": 0 + } + ], + "outputs": [], + "rewrites": [ + "jsa_contrib_reported", + "jsa_income_reported", + "esa_income_reported", + "income_support_reported", + "working_tax_credit_reported", + "child_tax_credit_reported", + "sda_reported", + "ssmg_reported", + "iidb_reported", + "afcs_reported", + "bsp_reported", + "is_disabled_for_benefits", + "is_enhanced_disabled_for_benefits", + "is_severely_disabled_for_benefits", + "receives_benefits_in_own_right", + "would_claim_uc" + ], + "source": "Family Resources Survey 2024-25 benefit reports carried through the SPI support channel, with the UK take-up contract's Universal Credit rate.", + "stage": "spi_benefit_coherence", + "survey": "Family Resources Survey 2024-25" + }, "spi_housing_shell": { "artifacts": [], "grain": "household", @@ -4647,7 +4733,7 @@ 2000000 ], "candidate_order": "person_id ascending breaks equal draw keys", - "candidate_population": "raw FRS base channel adults aged 16 and over", + "candidate_population": "raw FRS base channel claimants and partners (is_uc_claimant) aged 16 and over", "carrier_column": "person_is_spi_income_band_carrier", "clone_index": 2, "conservation": "exact_total", @@ -4870,7 +4956,7 @@ "artifacts": [], "grain": "benunit", "nonnegative_outputs": [], - "notes": "Runs after the last universal_credit_reported writer and before CGT cloning. Redraws only SPI post-fill reporters from weighted base-FRS reporter capital within dependent-children band by is_uc_couple cells (two retained FRS claimant/partner roles, independently of legal is_married), then applies the monotone reported-UC OR refresh.", + "notes": "Runs after the last universal_credit_reported writer and before CGT cloning. Redraws every SPI benefit unit's capital, since the channel's incomes are SPI draws and the copied FRS answer no longer belongs to the unit (uk-data#495, microcosm#1095), from weighted base-FRS units with available capital in cells of UC reporter status by financial investment income band (interest, dividends and other investment income; property income is excluded because TOTCAPB4 counts accounts and assets) by is_uc_couple (two retained FRS claimant/partner roles, independently of legal is_married) by dependent-children band. A cell with fewer than 20 donors widens in the declared coarsening order, and reporter status is never coarsened. It then applies the monotone reported-UC OR refresh.", "operations": [ { "aggregates": { @@ -4881,6 +4967,12 @@ "method": "any_positive" }, { + "coarsening": [ + "merge dependent-children bands", + "drop couple status", + "merge adjacent investment-income bands", + "reporter status only" + ], "couple_status": "is_uc_couple", "dependent_children_bands": [ "0", @@ -4888,12 +4980,22 @@ "2", "3+" ], - "donor_rows": "base_frs_reporters_with_available_capital", + "donor_rows": "base_frs_with_available_capital", "draw": "weighted_empirical", "identity": "benunit_id", + "investment_income": "savings_interest_income + dividend_income + other_investment_income, summed over benefit-unit members", + "investment_income_band_edges": [ + 0, + 240, + 640, + 2000, + 8000 + ], "kind": "redraw_spi_reporter_capital", + "minimum_cell_donors": 20, "output": "frs_benunit_capital", - "rows": "spi_channel_post_fill_reporters", + "reporter_status": "universal_credit_reported_anchor", + "rows": "spi_channel", "salt": "frs_benunit_capital", "seed": 0, "weight_mapping": "household_to_benunit" @@ -5295,7 +5397,7 @@ "mortgage_debt", "consumer_debt" ], - "notes": "Ports incumbent WAS round-8 wealth imputation with signed E5 differences: exact lower-case column matching replaces the fuzzy r/w fallback; cash ISA uses DVCISAVR8_aggr and stocks-and-shares ISA uses DVIISAVR8_aggr; private pension wealth (WAS total private pension wealth less the current defined-benefit component; DB-type components at the SCAPE rate, money-purchase components at reported fund values) is drawn as its own output private_pension_wealth and no longer folded into corporate_wealth, which keeps only the share-like holdings - pension rights are disregarded capital in every means test (UC Regs 2013 Sch 10 para 10 and the HB/JSA/ESA/IS/SPC parallels; uk-data#452) - and the downstream chain segment conditions on both components; each chain segment starts its own fit and draw RNG streams from a child seed derived deterministically from the declared seed (start_chain respawns from the model seed on every call, so one shared model coupled the k-th target of every segment); corporate_wealth folds stocks-and-shares ISA after drawing corporate_wealth_excl_isa; recipient Northern Ireland regions are mapped to Wales for prediction only; student_loan_balance is allocated by household id rather than the incumbent positional off-by-one. Tenure enters every chain segment as one four-way category built the same way on both sides (microcosm#1063): the donor's from Ten1R8 and DVPriRntR8 (owned outright; buying with a mortgage or part rent, part mortgage; rented or rent-free from a private landlord; rented from a council or housing association), the recipient's from the frame's tenure_type (council and housing association together), so the stage reads no engine tenure formula. Two columns are structural in tenure and are fitted and drawn inside their stratum only, zero by rule elsewhere: main_residence_value on the owner tenures (every WAS owner has a positive value and no renter has one) and main_residence_mortgage (TotMortR8) on the mortgaged tenure. mortgage_debt is HMortGR8, all of the household's mortgages, and is derived as the main-residence mortgage plus the mortgages on other property (other_mortgage, HMortGR8 less TotMortR8 on the donor: buy-to-let, second homes and the rest), which are held on every tenure and drawn without a stratum, so an outright owner's or a renter's buy-to-let keeps its mortgage beside the property it is secured on (OthMortR8_sum is read for the receipt only); the donor's conditioning copy carries the same rule, so consumer_debt is fitted on values recipients can hold. Totals are not drawn: property_wealth is the sum of land, the main residence, other houses, buildings and a drawn remainder (buy-to-let, overseas and other property), gross_financial_wealth is savings, the cash ISA, the share-like holdings and a drawn remainder, and net_financial_wealth is gross less consumer debt and the student loan balance - identities the pinned tab satisfies on every row and the cleaning step refuses a donor that breaks. A sum of donor-valued components that leaves the donor's range for the total gives up the excess from the remainder first, and the receipt counts the rows. Eight chain segments, each with its own child seed: land; the main residence; the other property components; pension and share-like wealth; the financial components, vehicles and the student loan balance; the main-residence mortgage; the other mortgages; consumer debt. HFINWNTR8_exSLC_Sum is net financial wealth excluding student loans, so gross less it is the non-student-loan financial liabilities; UKDS SN 7215 documentation is the codebook. Engine predictors materialize at their native entity and person/benunit values are summed to household, reproducing the incumbent map_to=household semantics; region is one-hot encoded jointly across donor and recipient (the incumbent's dummy encoding), with unmapped donor GOR codes becoming all-zero dummy rows. The WAS and FRS predictor definitions are not fully like-for-like and are ported as-is; raw WAS missing values are blanket-filled with zero; UKDS negative sentinel codes (-9/-8/-7/-6) are recoded to zero for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8's -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded.", + "notes": "Ports incumbent WAS round-8 wealth imputation with signed E5 differences: exact lower-case column matching replaces the fuzzy r/w fallback; cash ISA uses DVCISAVR8_aggr and stocks-and-shares ISA uses DVIISAVR8_aggr; private pension wealth (WAS total private pension wealth less the current defined-benefit component; DB-type components at the SCAPE rate, money-purchase components at reported fund values) is drawn as its own output private_pension_wealth and no longer folded into corporate_wealth, which keeps only the share-like holdings - pension rights are disregarded capital in every means test (UC Regs 2013 Sch 10 para 10 and the HB/JSA/ESA/IS/SPC parallels; uk-data#452) - and the downstream chain segment conditions on both components; each chain segment starts its own fit and draw RNG streams from a child seed derived deterministically from the declared seed (start_chain respawns from the model seed on every call, so one shared model coupled the k-th target of every segment); corporate_wealth folds stocks-and-shares ISA after drawing corporate_wealth_excl_isa; recipient Northern Ireland regions are mapped to Wales for prediction only; student_loan_balance is allocated by household id rather than the incumbent positional off-by-one. Tenure enters every chain segment as one four-way category built the same way on both sides (microcosm#1063): the donor's from Ten1R8 and DVPriRntR8 (owned outright; buying with a mortgage or part rent, part mortgage; rented or rent-free from a private landlord; rented from a council or housing association), the recipient's from the frame's tenure_type (council and housing association together), so the stage reads no engine tenure formula. Two columns are structural in tenure and are fitted and drawn inside their stratum only, zero by rule elsewhere: main_residence_value on the owner tenures (every WAS owner has a positive value and no renter has one) and main_residence_mortgage (TotMortR8) on the mortgaged tenure. mortgage_debt is HMortGR8, all of the household's mortgages, and is derived as the main-residence mortgage plus the mortgages on other property (other_mortgage, HMortGR8 less TotMortR8 on the donor: buy-to-let, second homes and the rest), which are held on every tenure and drawn without a stratum, so an outright owner's or a renter's buy-to-let keeps its mortgage beside the property it is secured on (OthMortR8_sum is read for the receipt only); the donor's conditioning copy carries the same rule, so consumer_debt is fitted on values recipients can hold. Totals are not drawn: property_wealth is the sum of land, the main residence, other houses, buildings and a drawn remainder (buy-to-let, overseas and other property), gross_financial_wealth is savings, the cash ISA, the share-like holdings and a drawn remainder, and net_financial_wealth is gross less consumer debt and the student loan balance - identities the pinned tab satisfies on every row and the cleaning step refuses a donor that breaks. A sum of donor-valued components that leaves the donor's range for the total gives up the excess from the remainder first, and the receipt counts the rows. Eight chain segments, each with its own child seed: land; the main residence; the other property components; pension and share-like wealth; the financial components, vehicles and the student loan balance; the main-residence mortgage; the other mortgages; consumer debt. HFINWNTR8_exSLC_Sum is net financial wealth excluding student loans, so gross less it is the non-student-loan financial liabilities; UKDS SN 7215 documentation is the codebook. Engine predictors materialize at their native entity and person/benunit values are summed to household, reproducing the incumbent map_to=household semantics; region is one-hot encoded jointly across donor and recipient (the incumbent's dummy encoding), with unmapped donor GOR codes becoming all-zero dummy rows. The WAS and FRS predictor definitions are not fully like-for-like and are ported as-is; raw WAS missing values are blanket-filled with zero; UKDS negative sentinel codes (-9/-8/-7/-6) are recoded to zero for the nonnegative-domain columns the licensed audit found carrying them (vcarnr8: 2 rows; HBedRmR8: 95.8 percent - the bedrooms question is effectively unasked in the WAS household file, predictor-quality revisit registered on microcosm#145) - a signed difference vs the incumbent, which trains on raw sentinels; DVPriRntR8's -9 is structural not-applicable so the private-renter reading is unchanged; genuinely negative domains are never recoded. The recipient council_tax predictor is the bill the household pays, council_tax less council_tax_rebate, the quantity the WAS donor records, since the spine's council_tax is the liability before council tax reduction (uk-data#496/#499, microcosm#1095). The donor council_tax is DVCTaxAmtAnnualR8, the annual amount paid (CTAmtR8 is one instalment), its children are NumChildR8 (NumCh18R8 overlaps NumAdultR8), and the recipient adults and children are the household's FRS claimants and partners and its other members (is_uc_claimant), which together make the household size on both sides; rental_income is the donor's net rent DVNetRentAmtAnnualR8_aggr against the household's property_income (uk-data#486/#495, microcosm#1095).", "operations": [ { "derived": { @@ -5304,7 +5406,8 @@ "corporate_wealth_excl_isa": "DVFESHARESR8_aggr + DVFShUKVR8_aggr + DVFCollVR8_aggr", "is_renting": "DVPriRntR8 == 1", "other_financial_assets": "HFINWR8_SUM - (DVSaValR8_aggr + DVCISAVR8_aggr + corporate_wealth), refused when negative", - "other_property_value": "DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative", + "other_property_value": "DVPropertyR8 - (DVhvalueR8 + DVHseValR8_sum + DVBltValR8_sum + DVBlDValR8_sum + DVLUKValR8_sum), refused when negative", + "other_residential_property_value": "DVHseValR8_sum + DVBltValR8_sum (houses other than the main residence plus buy-to-let property)", "private_pension_wealth": "totalpenr8_aggr - dvvaldbt_scaper8_aggr", "region": "GORR8 via incumbent REGIONS map", "stocks_and_shares_isa": "DVIISAVR8_aggr", @@ -5312,6 +5415,7 @@ "tenure_category": "Ten1R8 1 owned_outright; 2 or 3 owned_with_mortgage; 4 or 5 private_rent when DVPriRntR8 == 1, otherwise social_rent; any other code private_rent, counted in the receipt" }, "direct_maps": { + "council_tax": "DVCTaxAmtAnnualR8", "gross_financial_wealth": "HFINWR8_SUM", "main_residence_mortgage": "TotMortR8", "main_residence_value": "DVhvalueR8", @@ -5319,12 +5423,14 @@ "net_financial_wealth": "HFINWNTR8_Sum", "net_financial_wealth_exsl": "HFINWNTR8_exSLC_Sum", "non_residential_property_value": "DVBlDValR8_sum", + "num_adults": "NumAdultR8", + "num_children": "NumChildR8", "num_vehicles": "vcarnr8", "other_property_mortgage": "OthMortR8_sum", - "other_residential_property_value": "DVHseValR8_sum", "owned_land": "DVLUKValR8_sum", "private_rent_code": "DVPriRntR8", "property_wealth": "DVPropertyR8", + "rental_income": "DVNetRentAmtAnnualR8_aggr", "savings": "DVSaValR8_aggr", "tenure_code": "Ten1R8", "weight": "R8xshhwgt" @@ -5338,8 +5444,6 @@ "kind": "materialize_rules_engine_predictors", "predictors": [ "household_net_income", - "num_adults", - "num_children", "private_pension_income", "employment_income", "self_employment_income", @@ -5422,6 +5526,7 @@ "employment_income", "self_employment_income", "capital_income", + "rental_income", "num_bedrooms", "council_tax", "tenure_owned_with_mortgage", diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/househol.tab b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/househol.tab index 2a4c08784..c03bc276b 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/househol.tab +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/househol.tab @@ -1,136 +1,136 @@ -SERNUM GROSS4 GVTREGNO PTENTYP2 TYPEACC BEDROOM6 CTANNUAL CTBAND CTREBAMT ADULTH HRPNUM CSEWAMT CWATAMTD CWATAMT1 CSEWAMT1 WATSEWRT NIRATLIA RT2REBAM HHRENT SUBRENT TENTYP2 MORTINT STRUINS CHRGAMT1 CHRGAMT2 CHRGAMT3 CHRGAMT4 CHRGAMT5 CHRGAMT6 CHRGAMT7 CHRGAMT8 CHRGAMT9 -1 1.01 11 6 2 2 910.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -2 1.02 12 5 3 3 920.0 3 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -3 1.03 1 6 4 4 930.0 4 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -4 1.04 8 5 1 1 940.0 5 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -5 1.05 11 6 2 2 950.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -6 1.06 12 5 3 3 960.0 7 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -7 1.07 1 6 4 4 970.0 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -8 1.08 8 5 1 1 980.0 2 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -9 1.09 11 6 2 2 990.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -10 1.1 12 5 3 3 1000.0 4 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -11 1.11 1 6 4 4 1010.0 5 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -12 1.12 8 5 1 1 1020.0 6 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -13 1.13 11 6 2 2 1030.0 7 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -14 1.1400000000000001 12 5 3 3 1040.0 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -15 1.15 1 6 4 4 1050.0 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -16 1.16 8 5 1 1 1060.0 3 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -17 1.17 11 6 2 2 1070.0 4 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -18 1.18 12 5 3 3 1080.0 5 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -19 1.19 1 6 4 4 1090.0 6 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -20 1.2 8 5 1 1 1100.0 7 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -21 1.21 11 6 2 2 1110.0 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -22 1.22 12 5 3 3 1120.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -23 1.23 1 6 4 4 1130.0 3 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -24 1.24 8 5 1 1 1140.0 4 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -25 1.25 11 6 2 2 1150.0 5 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -26 1.26 12 5 3 3 1160.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -27 1.27 1 6 4 4 1170.0 7 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -28 1.28 8 5 1 1 1180.0 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -29 1.29 11 6 2 2 1190.0 2 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -30 1.3 12 5 3 3 1200.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -31 1.31 1 6 4 4 1210.0 4 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -32 1.32 8 5 1 1 1220.0 5 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -33 1.33 11 6 2 2 1230.0 6 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -34 1.34 12 5 3 3 1240.0 7 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -35 1.35 1 6 4 4 1250.0 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -36 1.3599999999999999 8 5 1 1 1260.0 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -37 1.37 11 6 2 2 1270.0 3 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -38 1.38 12 5 3 3 1280.0 4 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -39 1.3900000000000001 1 6 4 4 1290.0 5 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -40 1.4 8 5 1 1 1300.0 6 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -41 1.41 11 6 2 2 1310.0 7 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -42 1.42 12 5 3 3 1320.0 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -43 1.43 1 6 4 4 1330.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -44 1.44 8 5 1 1 1340.0 3 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -45 1.45 11 6 2 2 1350.0 4 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -46 1.46 12 5 3 3 1360.0 5 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -47 1.47 1 6 4 4 1370.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -48 1.48 8 5 1 1 1380.0 7 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -49 1.49 11 6 2 2 1390.0 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -50 1.5 12 5 3 3 1400.0 2 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -51 1.51 1 6 4 4 1410.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -52 1.52 8 5 1 1 1420.0 4 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -53 1.53 11 6 2 2 1430.0 5 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -54 1.54 12 5 3 3 1440.0 6 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -55 1.55 1 6 4 4 1450.0 7 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -56 1.56 8 5 1 1 1460.0 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -57 1.5699999999999998 11 6 2 2 1470.0 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -58 1.58 12 5 3 3 1480.0 3 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -59 1.5899999999999999 1 6 4 4 1490.0 4 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -60 1.6 8 5 1 1 1500.0 5 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -61 1.6099999999999999 11 6 2 2 1510.0 6 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -62 1.62 12 5 3 3 1520.0 7 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -63 1.63 1 6 4 4 1530.0 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -64 1.6400000000000001 8 5 1 1 1540.0 2 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -65 1.65 11 6 2 2 1550.0 3 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -66 1.6600000000000001 12 5 3 3 1560.0 4 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -67 1.67 1 6 4 4 1570.0 5 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -68 1.6800000000000002 8 5 1 1 1580.0 6 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -69 1.69 11 6 2 2 1590.0 7 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -70 1.7 12 5 3 3 1600.0 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -71 1.71 1 6 4 4 1610.0 2 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -72 1.72 8 5 1 1 1620.0 3 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -73 1.73 11 6 2 2 1630.0 4 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -74 1.74 12 5 3 3 1640.0 5 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -75 1.75 1 6 4 4 1650.0 6 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -76 1.76 8 5 1 1 1660.0 7 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -77 1.77 11 6 2 2 1670.0 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -78 1.78 12 5 3 3 1680.0 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -79 1.79 1 6 4 4 1690.0 3 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -80 1.8 8 5 1 1 1700.0 4 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -81 1.81 11 6 2 2 1710.0 5 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -82 1.8199999999999998 12 5 3 3 1720.0 6 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -83 1.83 1 6 4 4 1730.0 7 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -84 1.8399999999999999 8 5 1 1 1740.0 1 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -85 1.85 11 6 2 2 1750.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -86 1.8599999999999999 12 5 3 3 1760.0 3 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -87 1.87 1 6 4 4 1770.0 4 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -88 1.88 8 5 1 1 1780.0 5 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -89 1.8900000000000001 11 6 2 2 1790.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -90 1.9 12 5 3 3 1800.0 7 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -91 1.9100000000000001 1 6 4 4 1810.0 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -92 1.92 8 5 1 1 1820.0 2 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -93 1.9300000000000002 11 6 2 2 1830.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -94 1.94 12 5 3 3 1840.0 4 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -95 1.95 1 6 4 4 1850.0 5 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -96 1.96 8 5 1 1 1860.0 6 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -97 1.97 11 6 2 2 1870.0 7 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -98 1.98 12 5 3 3 1880.0 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -99 1.99 1 6 4 4 1890.0 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -100 2.0 8 5 1 1 1900.0 3 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -101 2.01 11 6 2 2 1910.0 4 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -102 2.02 12 5 3 3 1920.0 5 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -103 2.0300000000000002 1 6 4 4 1930.0 6 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -104 2.04 8 5 1 1 1940.0 7 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -105 2.05 11 6 2 2 1950.0 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -106 2.06 12 5 3 3 1960.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -107 2.0700000000000003 1 6 4 4 1970.0 3 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -108 2.08 8 5 1 1 1980.0 4 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -109 2.09 11 6 2 2 1990.0 5 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -110 2.1 12 5 3 3 2000.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -111 2.1100000000000003 1 6 4 4 2010.0 7 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -112 2.12 8 5 1 1 2020.0 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -113 2.13 11 6 2 2 2030.0 2 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -114 2.1399999999999997 12 5 3 3 2040.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -115 2.15 1 6 4 4 2050.0 4 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -116 2.16 8 5 1 1 2060.0 5 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -117 2.17 11 6 2 2 2070.0 6 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -118 2.1799999999999997 12 5 3 3 2080.0 7 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -119 2.19 1 6 4 4 2090.0 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -120 2.2 8 5 1 1 2100.0 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -121 2.21 11 6 2 2 2110.0 3 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -122 2.2199999999999998 12 5 3 3 2120.0 4 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -123 2.23 1 6 4 4 2130.0 5 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -124 2.24 8 5 1 1 2140.0 6 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -125 2.25 11 6 2 2 2150.0 7 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -126 2.26 12 5 3 3 2160.0 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -127 2.27 1 6 4 4 2170.0 2 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -128 2.2800000000000002 8 5 1 1 2180.0 3 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -129 2.29 11 6 2 2 2190.0 4 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -130 2.3 12 5 3 3 2200.0 5 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -131 2.31 1 6 4 4 2210.0 6 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -132 2.3200000000000003 8 5 1 1 2220.0 7 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -133 2.33 11 6 2 2 2230.0 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -134 2.34 12 5 3 3 2240.0 2 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -135 2.35 1 6 4 4 2250.0 3 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +SERNUM GROSS4 GVTREGNO PTENTYP2 TYPEACC BEDROOM6 CTANNUAL CTBAND CTDISC CT25D50D CTREB CTREBAMT ADULTH HRPNUM CSEWAMT CWATAMTD CWATAMT1 CSEWAMT1 WATSEWRT NIRATLIA RT2REBAM HHRENT SUBRENT TENTYP2 MORTINT STRUINS CHRGAMT1 CHRGAMT2 CHRGAMT3 CHRGAMT4 CHRGAMT5 CHRGAMT6 CHRGAMT7 CHRGAMT8 CHRGAMT9 +1 1.01 11 6 2 2 910.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +2 1.02 12 5 3 3 920.0 3 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +3 1.03 1 6 4 4 930.0 4 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +4 1.04 8 5 1 1 940.0 5 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +5 1.05 11 6 2 2 950.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +6 1.06 12 5 3 3 960.0 7 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +7 1.07 1 6 4 4 970.0 1 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +8 1.08 8 5 1 1 980.0 2 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +9 1.09 11 6 2 2 990.0 3 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +10 1.1 12 5 3 3 1000.0 4 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +11 1.11 1 6 4 4 1010.0 5 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +12 1.12 8 5 1 1 1020.0 6 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +13 1.13 11 6 2 2 1030.0 7 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +14 1.1400000000000001 12 5 3 3 1040.0 1 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +15 1.15 1 6 4 4 1050.0 2 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +16 1.16 8 5 1 1 1060.0 3 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +17 1.17 11 6 2 2 1070.0 4 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +18 1.18 12 5 3 3 1080.0 5 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +19 1.19 1 6 4 4 1090.0 6 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +20 1.2 8 5 1 1 1100.0 7 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +21 1.21 11 6 2 2 1110.0 1 1 1 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +22 1.22 12 5 3 3 1120.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +23 1.23 1 6 4 4 1130.0 3 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +24 1.24 8 5 1 1 1140.0 4 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +25 1.25 11 6 2 2 1150.0 5 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +26 1.26 12 5 3 3 1160.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +27 1.27 1 6 4 4 1170.0 7 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +28 1.28 8 5 1 1 1180.0 1 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +29 1.29 11 6 2 2 1190.0 2 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +30 1.3 12 5 3 3 1200.0 3 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +31 1.31 1 6 4 4 1210.0 4 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +32 1.32 8 5 1 1 1220.0 5 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +33 1.33 11 6 2 2 1230.0 6 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +34 1.34 12 5 3 3 1240.0 7 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +35 1.35 1 6 4 4 1250.0 1 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +36 1.3599999999999999 8 5 1 1 1260.0 2 1 2 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +37 1.37 11 6 2 2 1270.0 3 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +38 1.38 12 5 3 3 1280.0 4 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +39 1.3900000000000001 1 6 4 4 1290.0 5 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +40 1.4 8 5 1 1 1300.0 6 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +41 1.41 11 6 2 2 1310.0 7 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +42 1.42 12 5 3 3 1320.0 1 1 1 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +43 1.43 1 6 4 4 1330.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +44 1.44 8 5 1 1 1340.0 3 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +45 1.45 11 6 2 2 1350.0 4 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +46 1.46 12 5 3 3 1360.0 5 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +47 1.47 1 6 4 4 1370.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +48 1.48 8 5 1 1 1380.0 7 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +49 1.49 11 6 2 2 1390.0 1 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +50 1.5 12 5 3 3 1400.0 2 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +51 1.51 1 6 4 4 1410.0 3 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +52 1.52 8 5 1 1 1420.0 4 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +53 1.53 11 6 2 2 1430.0 5 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +54 1.54 12 5 3 3 1440.0 6 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +55 1.55 1 6 4 4 1450.0 7 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +56 1.56 8 5 1 1 1460.0 1 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +57 1.5699999999999998 11 6 2 2 1470.0 2 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +58 1.58 12 5 3 3 1480.0 3 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +59 1.5899999999999999 1 6 4 4 1490.0 4 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +60 1.6 8 5 1 1 1500.0 5 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +61 1.6099999999999999 11 6 2 2 1510.0 6 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +62 1.62 12 5 3 3 1520.0 7 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +63 1.63 1 6 4 4 1530.0 1 1 2 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +64 1.6400000000000001 8 5 1 1 1540.0 2 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +65 1.65 11 6 2 2 1550.0 3 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +66 1.6600000000000001 12 5 3 3 1560.0 4 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +67 1.67 1 6 4 4 1570.0 5 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +68 1.6800000000000002 8 5 1 1 1580.0 6 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +69 1.69 11 6 2 2 1590.0 7 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +70 1.7 12 5 3 3 1600.0 1 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +71 1.71 1 6 4 4 1610.0 2 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +72 1.72 8 5 1 1 1620.0 3 1 2 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +73 1.73 11 6 2 2 1630.0 4 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +74 1.74 12 5 3 3 1640.0 5 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +75 1.75 1 6 4 4 1650.0 6 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +76 1.76 8 5 1 1 1660.0 7 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +77 1.77 11 6 2 2 1670.0 1 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +78 1.78 12 5 3 3 1680.0 2 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +79 1.79 1 6 4 4 1690.0 3 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +80 1.8 8 5 1 1 1700.0 4 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +81 1.81 11 6 2 2 1710.0 5 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +82 1.8199999999999998 12 5 3 3 1720.0 6 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +83 1.83 1 6 4 4 1730.0 7 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +84 1.8399999999999999 8 5 1 1 1740.0 1 1 1 1 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +85 1.85 11 6 2 2 1750.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +86 1.8599999999999999 12 5 3 3 1760.0 3 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +87 1.87 1 6 4 4 1770.0 4 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +88 1.88 8 5 1 1 1780.0 5 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +89 1.8900000000000001 11 6 2 2 1790.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +90 1.9 12 5 3 3 1800.0 7 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +91 1.9100000000000001 1 6 4 4 1810.0 1 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +92 1.92 8 5 1 1 1820.0 2 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +93 1.9300000000000002 11 6 2 2 1830.0 3 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +94 1.94 12 5 3 3 1840.0 4 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +95 1.95 1 6 4 4 1850.0 5 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +96 1.96 8 5 1 1 1860.0 6 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +97 1.97 11 6 2 2 1870.0 7 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +98 1.98 12 5 3 3 1880.0 1 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +99 1.99 1 6 4 4 1890.0 2 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +100 2.0 8 5 1 1 1900.0 3 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +101 2.01 11 6 2 2 1910.0 4 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +102 2.02 12 5 3 3 1920.0 5 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +103 2.0300000000000002 1 6 4 4 1930.0 6 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +104 2.04 8 5 1 1 1940.0 7 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +105 2.05 11 6 2 2 1950.0 1 1 1 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +106 2.06 12 5 3 3 1960.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +107 2.0700000000000003 1 6 4 4 1970.0 3 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +108 2.08 8 5 1 1 1980.0 4 1 2 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +109 2.09 11 6 2 2 1990.0 5 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +110 2.1 12 5 3 3 2000.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +111 2.1100000000000003 1 6 4 4 2010.0 7 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +112 2.12 8 5 1 1 2020.0 1 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +113 2.13 11 6 2 2 2030.0 2 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +114 2.1399999999999997 12 5 3 3 2040.0 3 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +115 2.15 1 6 4 4 2050.0 4 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +116 2.16 8 5 1 1 2060.0 5 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +117 2.17 11 6 2 2 2070.0 6 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +118 2.1799999999999997 12 5 3 3 2080.0 7 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +119 2.19 1 6 4 4 2090.0 1 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +120 2.2 8 5 1 1 2100.0 2 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +121 2.21 11 6 2 2 2110.0 3 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +122 2.2199999999999998 12 5 3 3 2120.0 4 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +123 2.23 1 6 4 4 2130.0 5 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +124 2.24 8 5 1 1 2140.0 6 2 1 1.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +125 2.25 11 6 2 2 2150.0 7 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +126 2.26 12 5 3 3 2160.0 1 1 2 1 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +127 2.27 1 6 4 4 2170.0 2 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +128 2.2800000000000002 8 5 1 1 2180.0 3 2 1 2.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +129 2.29 11 6 2 2 2190.0 4 1 1 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +130 2.3 12 5 3 3 2200.0 5 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +131 2.31 1 6 4 4 2210.0 6 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +132 2.3200000000000003 8 5 1 1 2220.0 7 1 1 2 0.0 1 1 0.0 4.0 5.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +133 2.33 11 6 2 2 2230.0 1 2 1 1.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +134 2.34 12 5 3 3 2240.0 2 2 1 2.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 +135 2.35 1 6 4 4 2250.0 3 1 2 2 0.0 1 1 0.0 3.0 0.0 0.0 5.0 0.0 5 7.0 8.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/was.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/was.csv index 96bfd2181..e48820d50 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/was.csv +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/was.csv @@ -1,65 +1,65 @@ -CASER8,DVFLISAVR8_aggr,R8xshhwgt,DVLUKValR8_sum,DVPropertyR8,DVFESHARESR8_aggr,DVFShUKVR8_aggr,DVIISAVR8_aggR,DVCISAVR8_aggr,DVFCollVR8_aggr,totalpenr8_aggr,dvvaldbt_scaper8_aggr,NumAdultR8,NumCh18R8,DVGIPPENR8_AGGR,DVGISER8_AGGR,DVGIINVR8_aggr,DVGIEMPR8_AGGR,HBedRmR8,GORR8,DVPriRntR8,CTAmtR8,HFINWNTR8_Sum,HFINWNTR8_exSLC_Sum,HMortGR8,TotMortR8,OthMortR8_sum,Ten1R8,HFINWR8_SUM,DVhvalueR8,DVHseValR8_sum,DVBlDValR8_sum,DVTotinc_bhcR8,DVSaValR8_aggr,vcarnr8,Tot_LosR8_aggr,Tot_los_exc_SLCR8_aggr -1,5,1,10,104510,1,3,5,7,9,100,40,1,0,11,13,15,17,1,8,-9,900,555,555,2000,0,2000,1,555,100000,1000,3000,20000,500,0,9000,9000 -2,0,1.1000000000000001,0,102000,2,4,6,8,10,110,41,2,1,12,14,16,18,2,11,-9,910,-4464,541,10100,10100,0,2,581,102000,0,0,21000,520,1,14015,9010 -3,0,1.2,0,104000,3,5,7,9,11,120,42,3,2,13,15,17,19,3,12,-9,920,527,527,10200,10200,0,3,607,104000,0,0,22000,540,2,9020,9020 -4,0,1.3,0,1150,4,6,8,10,12,130,43,1,0,14,16,18,20,4,1,1,930,513,513,0,0,0,4,633,0,1150,0,23000,560,3,9030,9030 -5,0,1.3999999999999999,0,3240,5,7,9,11,13,140,44,2,1,15,17,19,21,5,8,2,940,-4521,499,0,0,0,4,659,0,0,3240,24000,580,0,14060,9040 -6,10,1.5,15,15,6,8,10,12,14,150,45,3,2,16,18,20,22,1,11,1,950,685,685,0,0,0,5,685,0,0,0,25000,600,1,9050,9050 -7,11,1.6000000000000001,0,113300,7,9,11,13,15,160,46,1,0,17,19,21,23,2,12,-9,960,671,671,2006,0,2006,1,711,112000,1300,0,26000,620,2,9060,9060 -8,0,1,0,114535,8,10,12,14,16,170,47,2,1,18,20,22,24,3,1,-9,970,-4378,657,10700,10700,0,2,737,114000,0,0,27000,640,3,14105,9070 -9,0,1.1000000000000001,0,119480,9,11,13,15,17,180,48,3,2,19,21,23,25,4,8,-9,980,643,643,10800,10800,0,3,763,116000,0,3480,28000,660,0,9080,9080 -10,0,1.2,0,1450,10,12,14,16,18,190,49,1,0,20,22,24,26,5,11,1,990,629,629,0,0,0,4,789,0,1450,0,29000,680,1,9090,9090 -11,15,1.3,20,20,11,13,15,17,19,200,50,2,1,21,23,25,27,1,12,2,1000,-4235,815,0,0,0,4,815,0,0,0,30000,700,2,14150,9100 -12,0,1.3999999999999999,0,0,12,14,16,18,20,210,51,3,2,22,24,26,28,2,1,1,1010,801,801,0,0,0,5,841,0,0,0,31000,720,3,9110,9110 -13,0,1.5,0,129320,13,15,17,19,21,220,52,1,0,23,25,27,29,3,8,-9,1020,787,787,2012,0,2012,1,867,124000,1600,3720,32000,740,0,9120,9120 -14,0,1.6000000000000001,0,126000,14,16,18,20,22,230,53,2,1,24,26,28,30,4,11,-9,1030,-4292,773,11300,11300,0,2,893,126000,0,0,33000,760,1,14195,9130 -15,19,1,0,128570,15,17,19,21,23,240,54,3,2,25,27,29,31,5,12,-9,1040,759,759,11400,11400,0,3,919,128000,0,0,34000,780,2,9140,9140 -16,0,1.1000000000000001,25,1775,16,18,20,22,24,250,55,1,0,26,28,30,32,1,1,1,1050,945,945,0,0,0,4,945,0,1750,0,35000,800,3,9150,9150 -17,0,1.2,0,3960,17,19,21,23,25,260,56,2,1,27,29,31,33,2,8,2,1060,-4149,931,0,0,0,4,971,0,0,3960,36000,820,0,14240,9160 -18,0,1.3,0,0,18,20,22,24,26,270,57,3,2,28,30,32,34,3,11,1,1070,917,917,0,0,0,5,997,0,0,0,37000,840,1,9170,9170 -19,0,1.3999999999999999,0,137900,19,21,23,25,27,280,58,1,0,29,31,33,35,4,12,-9,1080,903,903,2018,0,2018,1,1023,136000,1900,0,38000,860,2,9180,9180 -20,0,1.5,0,138000,20,22,24,26,28,290,59,2,1,30,32,34,36,5,1,-9,1090,-4206,889,11900,11900,0,2,1049,138000,0,0,39000,880,3,14285,9190 -21,5,1.6000000000000001,30,144230,21,23,25,27,29,300,60,3,2,31,33,35,37,1,8,-9,1100,1075,1075,12000,12000,0,3,1075,140000,0,4200,40000,900,0,9200,9200 -22,0,1,0,2655,22,24,26,28,30,310,61,1,0,32,34,36,38,2,11,1,1110,1061,1061,0,0,0,4,1101,0,2050,0,41000,920,1,9210,9210 -23,0,1.1000000000000001,0,0,23,25,27,29,31,320,62,2,1,33,35,37,39,3,12,2,1120,-4063,1047,0,0,0,4,1127,0,0,0,42000,940,2,14330,9220 -24,0,1.2,0,0,24,26,28,30,32,330,63,3,2,34,36,38,40,4,1,1,1130,1033,1033,0,0,0,5,1153,0,0,0,43000,960,3,9230,9230 -25,9,1.3,0,154640,25,27,29,31,33,340,64,1,0,35,37,39,41,5,8,-9,1140,1019,1019,2024,0,2024,1,1179,148000,2200,4440,44000,980,0,9240,9240 -26,0,1.3999999999999999,35,150035,26,28,30,32,34,350,65,2,1,36,38,40,42,1,11,-9,1150,-3920,1205,12500,12500,0,2,1205,150000,0,0,45000,1000,1,14375,9250 -27,0,1.5,0,152000,27,29,31,33,35,360,66,3,2,37,39,41,43,2,12,-9,1160,1191,1191,12600,12600,0,3,1231,152000,0,0,46000,1020,2,9260,9260 -28,0,1.6000000000000001,0,2350,28,30,32,34,36,370,67,1,0,38,40,42,44,3,1,1,1170,1177,1177,0,0,0,4,1257,0,2350,0,47000,1040,3,9270,9270 -29,13,1,0,5320,29,31,33,35,37,380,68,2,1,39,41,43,45,4,8,2,1180,-3977,1163,0,0,0,4,1283,0,0,4680,48000,1060,0,14420,9280 -30,0,1.1000000000000001,0,0,30,32,34,36,38,390,69,3,2,40,42,44,46,5,11,1,1190,1149,1149,0,0,0,5,1309,0,0,0,49000,1080,1,9290,9290 -31,0,1.2,40,162540,31,33,35,37,39,400,70,1,0,41,43,45,47,1,12,-9,1200,1335,1335,2030,0,2030,1,1335,160000,2500,0,50000,1100,2,9300,9300 -32,0,1.3,0,162000,32,34,36,38,40,410,71,2,1,42,44,46,48,2,1,-9,1210,-3834,1321,13100,13100,0,2,1361,162000,0,0,51000,1120,3,14465,9310 -33,0,1.3999999999999999,0,168920,33,35,37,39,41,420,72,3,2,43,45,47,49,3,8,-9,1220,1307,1307,13200,13200,0,3,1387,164000,0,4920,52000,1140,0,9320,9320 -34,0,1.5,0,2650,34,36,38,40,42,430,73,1,0,44,46,48,50,4,11,1,1230,1293,1293,0,0,0,4,1413,0,2650,0,53000,1160,1,9330,9330 -35,19,1.6000000000000001,0,0,35,37,39,41,43,440,74,2,1,45,47,49,51,5,12,2,1240,-3891,1279,0,0,0,4,1439,0,0,0,54000,1180,2,14510,9340 -36,0,1,45,720,36,38,40,42,44,450,75,3,2,46,48,50,52,1,1,1,1250,1465,1465,0,0,0,5,1465,0,0,0,55000,1200,3,9350,9350 -37,0,1.1000000000000001,0,179960,37,39,41,43,45,460,76,1,0,47,49,51,53,2,8,-9,1260,1451,1451,2036,0,2036,1,1491,172000,2800,5160,56000,1220,0,9360,9360 -38,0,1.2,0,174000,38,40,42,44,46,470,77,2,1,48,50,52,54,3,11,-9,1270,-3748,1437,13700,13700,0,2,1517,174000,0,0,57000,1240,1,14555,9370 -39,23,1.3,0,176000,39,41,43,45,47,480,78,3,2,49,51,53,55,4,12,-9,1280,1423,1423,13800,13800,0,3,1543,176000,0,0,58000,1260,2,9380,9380 -40,0,1.3999999999999999,0,2950,40,42,44,46,48,490,79,1,0,50,52,54,56,5,1,1,1290,1409,1409,0,0,0,4,1569,0,2950,0,59000,1280,3,9390,9390 -41,0,1.5,50,5450,41,43,45,47,49,500,80,2,1,51,53,55,57,1,8,2,1300,-3605,1595,0,0,0,4,1595,0,0,5400,60000,1300,0,14600,9400 -42,0,1.6000000000000001,0,0,42,44,46,48,50,510,81,3,2,52,54,56,58,2,11,1,1310,1581,1581,0,0,0,5,1621,0,0,0,61000,1320,1,9410,9410 -43,7,1,0,187810,43,45,47,49,51,520,82,1,0,53,55,57,59,3,12,-9,1320,1567,1567,2042,0,2042,1,1647,184000,3100,0,62000,1340,2,9420,9420 -44,0,1.1000000000000001,0,186000,44,46,48,50,52,530,83,2,1,54,56,58,60,4,1,-9,1330,-3662,1553,14300,14300,0,2,1673,186000,0,0,63000,1360,3,14645,9430 -45,0,1.2,0,193640,45,47,49,51,53,540,84,3,2,55,57,59,61,5,8,-9,1340,1539,1539,14400,14400,0,3,1699,188000,0,5640,64000,1380,0,9440,9440 -46,0,1.3,55,3305,46,48,50,52,54,550,85,1,0,56,58,60,62,1,11,1,1350,1725,1725,0,0,0,4,1725,0,3250,0,65000,1400,1,9450,9450 -47,0,1.3999999999999999,0,0,47,49,51,53,55,560,86,2,1,57,59,61,63,2,12,2,1360,-3519,1711,0,0,0,4,1751,0,0,0,66000,1420,2,14690,9460 -48,0,1.5,0,0,48,50,52,54,56,570,87,3,2,58,60,62,64,3,1,1,1370,1697,1697,0,0,0,5,1777,0,0,0,67000,1440,3,9470,9470 -49,13,1.6000000000000001,0,205280,49,51,53,55,57,580,88,1,0,59,61,63,65,4,8,-9,1380,1683,1683,2048,0,2048,1,1803,196000,3400,5880,68000,1460,0,9480,9480 -50,0,1,0,198745,50,52,54,56,58,590,89,2,1,60,62,64,66,5,11,-9,1390,-3576,1669,14900,14900,0,2,1829,198000,0,0,69000,1480,1,14735,9490 -51,0,1.1000000000000001,60,200060,51,53,55,57,59,600,90,3,2,61,63,65,67,1,12,-9,1400,1855,1855,15000,15000,0,3,1855,200000,0,0,70000,1500,2,9500,9500 -52,0,1.2,0,3550,52,54,56,58,60,610,91,1,0,62,64,66,68,2,1,1,1410,1841,1841,0,0,0,4,1881,0,3550,0,71000,1520,3,9510,9510 -53,17,1.3,0,6120,53,55,57,59,61,620,92,2,1,63,65,67,69,3,8,2,1420,-3433,1827,0,0,0,4,1907,0,0,6120,72000,1540,0,14780,9520 -54,0,1.3999999999999999,0,0,54,56,58,60,62,630,93,3,2,64,66,68,70,4,11,1,1430,1813,1813,0,0,0,5,1933,0,0,0,73000,1560,1,9530,9530 -55,0,1.5,0,211700,55,57,59,61,63,640,94,1,0,65,67,69,71,5,12,-9,1440,1799,1799,2054,0,2054,1,1959,208000,3700,0,74000,1580,2,9540,9540 -56,0,1.6000000000000001,65,210065,56,58,60,62,64,650,95,2,1,66,68,70,72,1,1,-9,1450,-3290,1985,15500,15500,0,2,1985,210000,0,0,75000,1600,3,14825,9550 -57,21,1,0,219140,57,59,61,63,65,660,96,3,2,67,69,71,73,2,8,-9,1460,1971,1971,15600,15600,0,3,2011,212000,0,6360,76000,1620,0,9560,9560 -58,0,1.1000000000000001,0,3850,58,60,62,64,66,670,97,1,0,68,70,72,74,3,11,1,1470,1957,1957,0,0,0,4,2037,0,3850,0,77000,1640,1,9570,9570 -59,0,1.2,0,0,59,61,63,65,67,680,98,2,1,69,71,73,75,4,12,2,1480,-3347,1943,0,0,0,4,2063,0,0,0,78000,1660,2,14870,9580 -60,0,1.3,0,0,60,62,64,66,68,690,99,3,2,70,72,74,76,5,1,1,1490,1929,1929,0,0,0,5,2089,0,0,0,79000,1680,3,9590,9590 -61,0,1.3999999999999999,70,230670,61,63,65,67,69,700,100,1,0,71,73,75,77,1,8,-9,1500,2115,2115,2060,0,2060,1,2115,220000,4000,6600,80000,1700,0,9600,9600 -62,0,1.5,0,222000,62,64,66,68,70,710,101,2,1,72,74,76,78,2,11,-9,1510,-3204,2101,16100,16100,0,2,2141,222000,0,0,81000,1720,1,14915,9610 -63,7,1.6000000000000001,0,224000,63,65,67,69,71,720,102,3,2,73,75,77,79,3,12,-9,1520,2087,2087,16200,16200,0,3,2167,224000,0,0,82000,1740,2,9620,9620 -64,0,1,0,4965,64,66,68,70,72,730,103,1,0,74,76,78,80,4,1,1,1530,2073,2073,0,0,0,4,2193,0,4150,0,83000,1760,3,9630,9630 +CASER8,DVFLISAVR8_aggr,R8xshhwgt,DVLUKValR8_sum,DVPropertyR8,DVFESHARESR8_aggr,DVFShUKVR8_aggr,DVIISAVR8_aggR,DVCISAVR8_aggr,DVFCollVR8_aggr,totalpenr8_aggr,dvvaldbt_scaper8_aggr,NumAdultR8,NumChildR8,DVGIPPENR8_AGGR,DVGISER8_AGGR,DVGIINVR8_aggr,DVGIEMPR8_AGGR,HBedRmR8,GORR8,DVPriRntR8,DVCTaxAmtAnnualR8,DVNetRentAmtAnnualR8_aggr,HFINWNTR8_Sum,HFINWNTR8_exSLC_Sum,HMortGR8,TotMortR8,OthMortR8_sum,Ten1R8,HFINWR8_SUM,DVhvalueR8,DVHseValR8_sum,DVBltValR8_sum,DVBlDValR8_sum,DVTotinc_bhcR8,DVSaValR8_aggr,vcarnr8,Tot_LosR8_aggr,Tot_los_exc_SLCR8_aggr +1,5,1,10,104510,1,3,5,7,9,100,40,1,0,11,13,15,17,1,8,-9,900,2000,555,555,2000,0,2000,1,555,100000,1000,0,3000,20000,500,0,9000,9000 +2,0,1.1000000000000001,0,142500,2,4,6,8,10,110,41,2,1,12,14,16,18,2,11,-9,910,2040,-4464,541,10100,10100,0,2,581,102000,0,40500,0,21000,520,1,14015,9010 +3,0,1.2,0,104000,3,5,7,9,11,120,42,3,2,13,15,17,19,3,12,-9,920,0,527,527,10200,10200,0,3,607,104000,0,0,0,22000,540,2,9020,9020 +4,0,1.3,0,1150,4,6,8,10,12,130,43,1,0,14,16,18,20,4,1,1,930,2120,513,513,0,0,0,4,633,0,1150,0,0,23000,560,3,9030,9030 +5,0,1.3999999999999999,0,3240,5,7,9,11,13,140,44,2,1,15,17,19,21,5,8,2,940,0,-4521,499,0,0,0,4,659,0,0,0,3240,24000,580,0,14060,9040 +6,10,1.5,15,15,6,8,10,12,14,150,45,3,2,16,18,20,22,1,11,1,950,0,685,685,0,0,0,5,685,0,0,0,0,25000,600,1,9050,9050 +7,11,1.6000000000000001,0,113300,7,9,11,13,15,160,46,1,0,17,19,21,23,2,12,-9,960,2240,671,671,2006,0,2006,1,711,112000,1300,0,0,26000,620,2,9060,9060 +8,0,1,0,158035,8,10,12,14,16,170,47,2,1,18,20,22,24,3,1,-9,970,2280,-4378,657,10700,10700,0,2,737,114000,0,43500,0,27000,640,3,14105,9070 +9,0,1.1000000000000001,0,119480,9,11,13,15,17,180,48,3,2,19,21,23,25,4,8,-9,980,0,643,643,10800,10800,0,3,763,116000,0,0,3480,28000,660,0,9080,9080 +10,0,1.2,0,1450,10,12,14,16,18,190,49,1,0,20,22,24,26,5,11,1,990,2360,629,629,0,0,0,4,789,0,1450,0,0,29000,680,1,9090,9090 +11,15,1.3,20,20,11,13,15,17,19,200,50,2,1,21,23,25,27,1,12,2,1000,0,-4235,815,0,0,0,4,815,0,0,0,0,30000,700,2,14150,9100 +12,0,1.3999999999999999,0,0,12,14,16,18,20,210,51,3,2,22,24,26,28,2,1,1,1010,0,801,801,0,0,0,5,841,0,0,0,0,31000,720,3,9110,9110 +13,0,1.5,0,129320,13,15,17,19,21,220,52,1,0,23,25,27,29,3,8,-9,1020,2480,787,787,2012,0,2012,1,867,124000,1600,0,3720,32000,740,0,9120,9120 +14,0,1.6000000000000001,0,172500,14,16,18,20,22,230,53,2,1,24,26,28,30,4,11,-9,1030,2520,-4292,773,11300,11300,0,2,893,126000,0,46500,0,33000,760,1,14195,9130 +15,19,1,0,128570,15,17,19,21,23,240,54,3,2,25,27,29,31,5,12,-9,1040,0,759,759,11400,11400,0,3,919,128000,0,0,0,34000,780,2,9140,9140 +16,0,1.1000000000000001,25,1775,16,18,20,22,24,250,55,1,0,26,28,30,32,1,1,1,1050,2600,945,945,0,0,0,4,945,0,1750,0,0,35000,800,3,9150,9150 +17,0,1.2,0,3960,17,19,21,23,25,260,56,2,1,27,29,31,33,2,8,2,1060,0,-4149,931,0,0,0,4,971,0,0,0,3960,36000,820,0,14240,9160 +18,0,1.3,0,0,18,20,22,24,26,270,57,3,2,28,30,32,34,3,11,1,1070,0,917,917,0,0,0,5,997,0,0,0,0,37000,840,1,9170,9170 +19,0,1.3999999999999999,0,137900,19,21,23,25,27,280,58,1,0,29,31,33,35,4,12,-9,1080,2720,903,903,2018,0,2018,1,1023,136000,1900,0,0,38000,860,2,9180,9180 +20,0,1.5,0,187500,20,22,24,26,28,290,59,2,1,30,32,34,36,5,1,-9,1090,2760,-4206,889,11900,11900,0,2,1049,138000,0,49500,0,39000,880,3,14285,9190 +21,5,1.6000000000000001,30,144230,21,23,25,27,29,300,60,3,2,31,33,35,37,1,8,-9,1100,0,1075,1075,12000,12000,0,3,1075,140000,0,0,4200,40000,900,0,9200,9200 +22,0,1,0,2655,22,24,26,28,30,310,61,1,0,32,34,36,38,2,11,1,1110,2840,1061,1061,0,0,0,4,1101,0,2050,0,0,41000,920,1,9210,9210 +23,0,1.1000000000000001,0,0,23,25,27,29,31,320,62,2,1,33,35,37,39,3,12,2,1120,0,-4063,1047,0,0,0,4,1127,0,0,0,0,42000,940,2,14330,9220 +24,0,1.2,0,0,24,26,28,30,32,330,63,3,2,34,36,38,40,4,1,1,1130,0,1033,1033,0,0,0,5,1153,0,0,0,0,43000,960,3,9230,9230 +25,9,1.3,0,154640,25,27,29,31,33,340,64,1,0,35,37,39,41,5,8,-9,1140,2960,1019,1019,2024,0,2024,1,1179,148000,2200,0,4440,44000,980,0,9240,9240 +26,0,1.3999999999999999,35,202535,26,28,30,32,34,350,65,2,1,36,38,40,42,1,11,-9,1150,3000,-3920,1205,12500,12500,0,2,1205,150000,0,52500,0,45000,1000,1,14375,9250 +27,0,1.5,0,152000,27,29,31,33,35,360,66,3,2,37,39,41,43,2,12,-9,1160,0,1191,1191,12600,12600,0,3,1231,152000,0,0,0,46000,1020,2,9260,9260 +28,0,1.6000000000000001,0,2350,28,30,32,34,36,370,67,1,0,38,40,42,44,3,1,1,1170,3080,1177,1177,0,0,0,4,1257,0,2350,0,0,47000,1040,3,9270,9270 +29,13,1,0,5320,29,31,33,35,37,380,68,2,1,39,41,43,45,4,8,2,1180,0,-3977,1163,0,0,0,4,1283,0,0,0,4680,48000,1060,0,14420,9280 +30,0,1.1000000000000001,0,0,30,32,34,36,38,390,69,3,2,40,42,44,46,5,11,1,1190,0,1149,1149,0,0,0,5,1309,0,0,0,0,49000,1080,1,9290,9290 +31,0,1.2,40,162540,31,33,35,37,39,400,70,1,0,41,43,45,47,1,12,-9,1200,3200,1335,1335,2030,0,2030,1,1335,160000,2500,0,0,50000,1100,2,9300,9300 +32,0,1.3,0,217500,32,34,36,38,40,410,71,2,1,42,44,46,48,2,1,-9,1210,3240,-3834,1321,13100,13100,0,2,1361,162000,0,55500,0,51000,1120,3,14465,9310 +33,0,1.3999999999999999,0,168920,33,35,37,39,41,420,72,3,2,43,45,47,49,3,8,-9,1220,0,1307,1307,13200,13200,0,3,1387,164000,0,0,4920,52000,1140,0,9320,9320 +34,0,1.5,0,2650,34,36,38,40,42,430,73,1,0,44,46,48,50,4,11,1,1230,3320,1293,1293,0,0,0,4,1413,0,2650,0,0,53000,1160,1,9330,9330 +35,19,1.6000000000000001,0,0,35,37,39,41,43,440,74,2,1,45,47,49,51,5,12,2,1240,0,-3891,1279,0,0,0,4,1439,0,0,0,0,54000,1180,2,14510,9340 +36,0,1,45,720,36,38,40,42,44,450,75,3,2,46,48,50,52,1,1,1,1250,0,1465,1465,0,0,0,5,1465,0,0,0,0,55000,1200,3,9350,9350 +37,0,1.1000000000000001,0,179960,37,39,41,43,45,460,76,1,0,47,49,51,53,2,8,-9,1260,3440,1451,1451,2036,0,2036,1,1491,172000,2800,0,5160,56000,1220,0,9360,9360 +38,0,1.2,0,232500,38,40,42,44,46,470,77,2,1,48,50,52,54,3,11,-9,1270,3480,-3748,1437,13700,13700,0,2,1517,174000,0,58500,0,57000,1240,1,14555,9370 +39,23,1.3,0,176000,39,41,43,45,47,480,78,3,2,49,51,53,55,4,12,-9,1280,0,1423,1423,13800,13800,0,3,1543,176000,0,0,0,58000,1260,2,9380,9380 +40,0,1.3999999999999999,0,2950,40,42,44,46,48,490,79,1,0,50,52,54,56,5,1,1,1290,3560,1409,1409,0,0,0,4,1569,0,2950,0,0,59000,1280,3,9390,9390 +41,0,1.5,50,5450,41,43,45,47,49,500,80,2,1,51,53,55,57,1,8,2,1300,0,-3605,1595,0,0,0,4,1595,0,0,0,5400,60000,1300,0,14600,9400 +42,0,1.6000000000000001,0,0,42,44,46,48,50,510,81,3,2,52,54,56,58,2,11,1,1310,0,1581,1581,0,0,0,5,1621,0,0,0,0,61000,1320,1,9410,9410 +43,7,1,0,187810,43,45,47,49,51,520,82,1,0,53,55,57,59,3,12,-9,1320,3680,1567,1567,2042,0,2042,1,1647,184000,3100,0,0,62000,1340,2,9420,9420 +44,0,1.1000000000000001,0,247500,44,46,48,50,52,530,83,2,1,54,56,58,60,4,1,-9,1330,3720,-3662,1553,14300,14300,0,2,1673,186000,0,61500,0,63000,1360,3,14645,9430 +45,0,1.2,0,193640,45,47,49,51,53,540,84,3,2,55,57,59,61,5,8,-9,1340,0,1539,1539,14400,14400,0,3,1699,188000,0,0,5640,64000,1380,0,9440,9440 +46,0,1.3,55,3305,46,48,50,52,54,550,85,1,0,56,58,60,62,1,11,1,1350,3800,1725,1725,0,0,0,4,1725,0,3250,0,0,65000,1400,1,9450,9450 +47,0,1.3999999999999999,0,0,47,49,51,53,55,560,86,2,1,57,59,61,63,2,12,2,1360,0,-3519,1711,0,0,0,4,1751,0,0,0,0,66000,1420,2,14690,9460 +48,0,1.5,0,0,48,50,52,54,56,570,87,3,2,58,60,62,64,3,1,1,1370,0,1697,1697,0,0,0,5,1777,0,0,0,0,67000,1440,3,9470,9470 +49,13,1.6000000000000001,0,205280,49,51,53,55,57,580,88,1,0,59,61,63,65,4,8,-9,1380,3920,1683,1683,2048,0,2048,1,1803,196000,3400,0,5880,68000,1460,0,9480,9480 +50,0,1,0,263245,50,52,54,56,58,590,89,2,1,60,62,64,66,5,11,-9,1390,3960,-3576,1669,14900,14900,0,2,1829,198000,0,64500,0,69000,1480,1,14735,9490 +51,0,1.1000000000000001,60,200060,51,53,55,57,59,600,90,3,2,61,63,65,67,1,12,-9,1400,0,1855,1855,15000,15000,0,3,1855,200000,0,0,0,70000,1500,2,9500,9500 +52,0,1.2,0,3550,52,54,56,58,60,610,91,1,0,62,64,66,68,2,1,1,1410,4040,1841,1841,0,0,0,4,1881,0,3550,0,0,71000,1520,3,9510,9510 +53,17,1.3,0,6120,53,55,57,59,61,620,92,2,1,63,65,67,69,3,8,2,1420,0,-3433,1827,0,0,0,4,1907,0,0,0,6120,72000,1540,0,14780,9520 +54,0,1.3999999999999999,0,0,54,56,58,60,62,630,93,3,2,64,66,68,70,4,11,1,1430,0,1813,1813,0,0,0,5,1933,0,0,0,0,73000,1560,1,9530,9530 +55,0,1.5,0,211700,55,57,59,61,63,640,94,1,0,65,67,69,71,5,12,-9,1440,4160,1799,1799,2054,0,2054,1,1959,208000,3700,0,0,74000,1580,2,9540,9540 +56,0,1.6000000000000001,65,277565,56,58,60,62,64,650,95,2,1,66,68,70,72,1,1,-9,1450,4200,-3290,1985,15500,15500,0,2,1985,210000,0,67500,0,75000,1600,3,14825,9550 +57,21,1,0,219140,57,59,61,63,65,660,96,3,2,67,69,71,73,2,8,-9,1460,0,1971,1971,15600,15600,0,3,2011,212000,0,0,6360,76000,1620,0,9560,9560 +58,0,1.1000000000000001,0,3850,58,60,62,64,66,670,97,1,0,68,70,72,74,3,11,1,1470,4280,1957,1957,0,0,0,4,2037,0,3850,0,0,77000,1640,1,9570,9570 +59,0,1.2,0,0,59,61,63,65,67,680,98,2,1,69,71,73,75,4,12,2,1480,0,-3347,1943,0,0,0,4,2063,0,0,0,0,78000,1660,2,14870,9580 +60,0,1.3,0,0,60,62,64,66,68,690,99,3,2,70,72,74,76,5,1,1,1490,0,1929,1929,0,0,0,5,2089,0,0,0,0,79000,1680,3,9590,9590 +61,0,1.3999999999999999,70,230670,61,63,65,67,69,700,100,1,0,71,73,75,77,1,8,-9,1500,4400,2115,2115,2060,0,2060,1,2115,220000,4000,0,6600,80000,1700,0,9600,9600 +62,0,1.5,0,292500,62,64,66,68,70,710,101,2,1,72,74,76,78,2,11,-9,1510,4440,-3204,2101,16100,16100,0,2,2141,222000,0,70500,0,81000,1720,1,14915,9610 +63,7,1.6000000000000001,0,224000,63,65,67,69,71,720,102,3,2,73,75,77,79,3,12,-9,1520,0,2087,2087,16200,16200,0,3,2167,224000,0,0,0,82000,1740,2,9620,9620 +64,0,1,0,4965,64,66,68,70,72,730,103,1,0,74,76,78,80,4,1,1,1530,4520,2073,2073,0,0,0,4,2193,0,4150,0,0,83000,1760,3,9630,9630 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json index 933b17ae0..38bf635ca 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json @@ -1 +1 @@ -{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"047d30937efb21e39259fdbed5597751e4f5a0c341ea583c7446e4c9c11eba48","time_period":"2024"},"population":null,"sources":["frs"],"structural":"create","weights":null},{"base":"create_uk_frs","citation":"","description":"Ownership boundary for the source-assembling root stage.","id":"frs_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"base":null,"citation":"","description":"Claim the cells assembled by the UK FRS root transform.","id":"frs_spine","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{},"population":"frs_spine.boundary","sources":[],"structural":"none","weights":null},{"base":"frs_spine.boundary","citation":"","description":"Ownership boundary before age_tail rewrites.","id":"age_tail.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"30628808d06d9829ebcbcf460cd355a01261e78c7c73e6006c75bec2e3d60c33","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","sic_industry_division"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"3381cd9f7a736514d5073c57480e07f5098890f3ca9ed3865392043594771eb9","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"836cb0f5a582fee1425190e96c9cb81bdef859bd236c8b6bc27660b6e3d0c2f8","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","pension_credit_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"067d31b7fbe733d1d182588705e9ce79df0c8e5f6e8f519314765af49b1b00d7","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_person_draws@1","mass":"conserve","outputs":[{"column":"would_claim_marriage_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_scp","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"attends_private_school_random_draw","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_childcare_spend_routed_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"e840b69cb05b5cbb76b97b4fcb296244ea843a005e4882459c7132664bb526c2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"5b8f0b361310c7cd3efbaae3762b347649b7d4afb9e9943131d9bef9266fc3c8","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"frs_education_grant_split.boundary","citation":"","description":"Freeze the assembled-spine gate population.","id":"frs_brma.checkpoint","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"8cfab42bcc250fdf1161b22e4fd988fbe8a0473af78f99afea4b1017556633ae","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"5145464dd063c46e60ee1d1b2ddfa9cb02ee3c1ad42e1bc3511f6e288e17e67d","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","maintenance_expenses","childcare_expenses","salary_sacrifice_reported","salary_sacrifice_asked","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_benefits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_social_security_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_taxable_termination_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_miscellaneous_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_state_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employed_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_earned_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_assessable_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"0155bff429399867190021eb7aa5f1cac73b0aea2e2cbddd4e85edc741b9646e","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","is_household_head","other_investment_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","would_claim_carers_allowance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"809f19fd33ff79ceda005e8cc3fa89ae40b297dceca26a7658b6259267987890","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_wealth@1","mass":"conserve","outputs":[{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"corporate_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"private_pension_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gross_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"net_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"savings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"num_vehicles","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cash_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"consumer_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"daeb769e5b18086a68d66f288fcc5e3f6180d27d0cb95fea63a0874c6089e876","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"46f12fdf9228f721d860ff7858b78b25406bb8737628acf63ac17d44d549f657","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"10e9b226ee1483c9465bec4c8fff6d2d4387bcdb5611907189c84d1645874ab5","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"59767eeb246755f4636e2abbbc9ab3370a64c6142e01cda21a12cb01be95e535","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.lcfs_consumption@1","mass":"conserve","outputs":[{"column":"food_and_non_alcoholic_beverages_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"alcohol_and_tobacco_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"clothing_and_footwear_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_water_and_electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_furnishings_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"health_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"transport_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"communication_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"recreation_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"education_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"restaurants_and_hotels_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"miscellaneous_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"petrol_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"diesel_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_fare_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_energy_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gas_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"348c64e464d10e32be48843cb0ddf4f357957306439975b860a15679ea3465b4","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"5a2b777d88315bcccb72477c088a136c634131e0bc1a339b7287217ee5cfd8d3","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"991be160f2f2c28cf7eadc911b3214aca8bf5be441676fe21a87ba12888c5c25","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"regional_property_uprating.boundary","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"7e94e034cad29c5bae566ffb875c42cddf3a1025c15496907e783ceff1144f8b","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_benunit_head","is_parent","person_support_channel","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"059f27ee687ee15385b246d43068b17aeecbe3645ccc41fd52fcad06a006a081","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"5f2f0410ec296be7119d7f58365658e72ee46b5e4397c37f97ce01e911a98960","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"4689e00cfcb038c11d78274e1771719bb61beca2d76966193495c15ab691061f","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["child_benefit_opts_out","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"child_benefit_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"30b37e1c4e122db18391c5f76f1a6d432aea970275bcda7a52126dacc923490b","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"ee30278543cc0297a5366d855b7753aa04af5518971594c193c52be36bf8a7b4","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","tax_free_savings_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"ff740a36b03dcda73b889aa43bde7cff5d178de7b3da38e487320c68342bf9a3","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"b79ce806015de2f1e1703fa68bf4ad871c6df54b5b32633c864632ab68919a48","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"3355ff2f5203104a68b0414b0f5e7c05e5c23e9ff89a88e7deb3e5ed6bf04a20","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"5fb69157cf25de5cf64b48da73fd3ece5a390bcb17a6fa345fb494e78a95581e","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"051e5ad02ae8f22986db97f513ad3d7dcc06da81f4cfa7ec5d01428f37748360","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","current_education","highest_education","salary_sacrifice_pre_conversion_pay","student_loan_repayments","student_loans"],"entity":"person","rows":"all"}],"kernel":"uk.stage.student_loans@1","mass":"conserve","outputs":[{"column":"student_loan_plan","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"f2936c5e22a0e9b097437e3f3aabaf06c4561d5c25a9b7c05e720a6553f73bbc","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null}],"sources":[{"codec":"csv-tables","description":"Content-bound UK FRS and donor fixture/source bundle.","name":"frs"}]} +{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"111bdab45b5ce00062961791bf9a80833edec811741f73b4af0d91d7a3d8c373","time_period":"2024"},"population":null,"sources":["frs"],"structural":"create","weights":null},{"base":"create_uk_frs","citation":"","description":"Ownership boundary for the source-assembling root stage.","id":"frs_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"base":null,"citation":"","description":"Claim the cells assembled by the UK FRS root transform.","id":"frs_spine","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"marital_status","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hours_worked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"care_hours","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_household_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_benunit_head","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_parent","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"miscellaneous_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_transfer_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"lump_sum_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loan_repayments","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_sick_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"statutory_maternity_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"student_loans","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"access_fund","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"healthy_start_vouchers","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_breakfasts","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_fruit_veg","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"free_school_meals","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"childcare_expenses","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_asked","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"incapacity_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_married","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dependent_children","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{},"population":"frs_spine.boundary","sources":[],"structural":"none","weights":null},{"base":"frs_spine.boundary","citation":"","description":"Ownership boundary before age_tail rewrites.","id":"age_tail.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"30628808d06d9829ebcbcf460cd355a01261e78c7c73e6006c75bec2e3d60c33","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","sic_industry_division"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"425beb2093c2f603e6b7394b98dcb129b2162b73447b6e6a7be33b537ff2ffe1","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"836cb0f5a582fee1425190e96c9cb81bdef859bd236c8b6bc27660b6e3d0c2f8","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","pension_credit_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"would_claim_uc_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"067d31b7fbe733d1d182588705e9ce79df0c8e5f6e8f519314765af49b1b00d7","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_person_draws@1","mass":"conserve","outputs":[{"column":"would_claim_marriage_allowance","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"would_claim_scp","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"attends_private_school_random_draw","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"tax_free_childcare_spend_routed_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"e840b69cb05b5cbb76b97b4fcb296244ea843a005e4882459c7132664bb526c2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"5b8f0b361310c7cd3efbaae3762b347649b7d4afb9e9943131d9bef9266fc3c8","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"frs_education_grant_split.boundary","citation":"","description":"Freeze the assembled-spine gate population.","id":"frs_brma.checkpoint","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"8cfab42bcc250fdf1161b22e4fd988fbe8a0473af78f99afea4b1017556633ae","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"d197d6fc2f9dc5918a26ef555d3d2934419f0a9a21ffa2e17379958c692e583d","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","maintenance_expenses","childcare_expenses","salary_sacrifice_reported","salary_sacrifice_asked","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_benefits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employment_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_social_security_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_taxable_termination_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_miscellaneous_employment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_other_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_state_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_employed_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_earned_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_total_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_assessable_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"savings_interest_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dividend_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"personal_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"tax_free_savings_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"attendance_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"state_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"carers_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"winter_fuel_allowance_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"70974ecb9e1a2ac495e0c95e6ccb8b08dfc8e7c5381a0026f470557e28065bf2","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","is_household_head","other_investment_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","would_claim_carers_allowance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"809f19fd33ff79ceda005e8cc3fa89ae40b297dceca26a7658b6259267987890","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_wealth@1","mass":"conserve","outputs":[{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"corporate_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"private_pension_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gross_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"net_financial_wealth","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"savings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"num_vehicles","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cash_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"consumer_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"9941b70870b0ced1ea1f51e9c9f12768005ea6c53ffdba1db3cb4e2ee030af87","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"46f12fdf9228f721d860ff7858b78b25406bb8737628acf63ac17d44d549f657","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"10e9b226ee1483c9465bec4c8fff6d2d4387bcdb5611907189c84d1645874ab5","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"59767eeb246755f4636e2abbbc9ab3370a64c6142e01cda21a12cb01be95e535","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.lcfs_consumption@1","mass":"conserve","outputs":[{"column":"food_and_non_alcoholic_beverages_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"alcohol_and_tobacco_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"clothing_and_footwear_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_water_and_electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_furnishings_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"health_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"transport_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"communication_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"recreation_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"education_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"restaurants_and_hotels_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"miscellaneous_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"petrol_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"diesel_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_fare_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_energy_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"electricity_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"gas_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"348c64e464d10e32be48843cb0ddf4f357957306439975b860a15679ea3465b4","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"a9ed8bb2f260e7ffa395de3eb5b0b4a6d26d9fed8a6f0758e827a56fdb0d3eab","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"a81e4cd867f0215836e2e1cf45dee0735ae7354c6d58e597072836475dabf841","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"regional_property_uprating.boundary","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"7e94e034cad29c5bae566ffb875c42cddf3a1025c15496907e783ceff1144f8b","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before spi_benefit_coherence rewrites.","id":"spi_benefit_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_benefit_coherence.","id":"spi_benefit_coherence","inputs":[{"columns":["benunit_support_channel","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["aa_category","age","attendance_allowance_reported","dla_m_category","dla_m_reported","dla_sc_category","dla_sc_reported","esa_contrib_reported","incapacity_benefit_reported","person_source_id","person_support_channel","pip_dl_category","pip_dl_reported","pip_m_category","pip_m_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_benefit_coherence@1","mass":"conserve","outputs":[{"column":"jsa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_benefit_coherence","stage_contract_sha256":"e2f10f92da81cafd34107b5eb6d0b82f1b9496e8c1de8afde1ff1c28e06fa300","time_period":"2024"},"population":"spi_benefit_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_benefit_coherence.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","is_benunit_head","is_parent","other_investment_income","person_support_channel","savings_interest_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"a28b6cfd6260a2c44e3e13860e4b560cbad2e25615c2a29dc1c70b71f593a1d5","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"5f2f0410ec296be7119d7f58365658e72ee46b5e4397c37f97ce01e911a98960","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"4689e00cfcb038c11d78274e1771719bb61beca2d76966193495c15ab691061f","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["child_benefit_opts_out","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"child_benefit_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"30b37e1c4e122db18391c5f76f1a6d432aea970275bcda7a52126dacc923490b","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"ee30278543cc0297a5366d855b7753aa04af5518971594c193c52be36bf8a7b4","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","tax_free_savings_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"ff740a36b03dcda73b889aa43bde7cff5d178de7b3da38e487320c68342bf9a3","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"b79ce806015de2f1e1703fa68bf4ad871c6df54b5b32633c864632ab68919a48","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","employment_income","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","employee_pension_contributions","pension_contributions_via_salary_sacrifice","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"3355ff2f5203104a68b0414b0f5e7c05e5c23e9ff89a88e7deb3e5ed6bf04a20","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"5fb69157cf25de5cf64b48da73fd3ece5a390bcb17a6fa345fb494e78a95581e","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","household_lifetime_isa_balance","household_local_bus_trips","food_and_non_alcoholic_beverages_consumption","alcohol_and_tobacco_consumption","clothing_and_footwear_consumption","housing_water_and_electricity_consumption","household_furnishings_consumption","health_consumption","transport_consumption","communication_consumption","recreation_consumption","education_consumption","restaurants_and_hotels_consumption","miscellaneous_consumption","petrol_spending","diesel_spending","bus_fare_spending","domestic_energy_consumption","electricity_consumption","gas_consumption","has_fuel_consumption","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","marital_status","hours_worked","care_hours","is_household_head","is_benunit_head","is_parent","is_uc_claimant","self_employment_income","private_pension_income","tax_free_savings_income","savings_interest_income","dividend_income","property_income","maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","student_loans","access_fund","education_grants","healthy_start_vouchers","free_school_breakfasts","free_school_fruit_veg","free_school_meals","council_tax_benefit_reported","maintenance_expenses","childcare_expenses","personal_pension_contributions","salary_sacrifice_reported","salary_sacrifice_asked","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","would_claim_carers_allowance","sda_reported","afcs_reported","ssmg_reported","pension_credit_reported","child_tax_credit_reported","working_tax_credit_reported","state_pension_reported","winter_fuel_allowance_reported","incapacity_benefit_reported","universal_credit_reported","pip_m_reported","pip_dl_reported","jsa_contrib_reported","jsa_income_reported","esa_contrib_reported","esa_income_reported","bsp_reported","relationship_to_head","ons_family_role","ons_family_index","employment_status","employment_sector","sic_industry_division","aa_category","dla_sc_category","dla_m_category","pip_m_category","pip_dl_category","is_disabled_for_benefits","is_enhanced_disabled_for_benefits","is_severely_disabled_for_benefits","current_education","highest_education","is_in_non_advanced_education","is_in_approved_training","age_started_or_accepted_current_education_or_training","is_before_universal_credit_qualifying_young_person_terminal_date","adult_ema","child_ema","receives_benefits_in_own_right","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","other_investment_income","hmrc_spi_employment_benefits","hmrc_spi_employment_expenses","hmrc_spi_other_social_security_income","hmrc_spi_taxable_termination_pay","hmrc_spi_miscellaneous_employment_income","hmrc_spi_other_income","hmrc_spi_state_pension_income","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"051e5ad02ae8f22986db97f513ad3d7dcc06da81f4cfa7ec5d01428f37748360","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","current_education","highest_education","salary_sacrifice_pre_conversion_pay","student_loan_repayments","student_loans"],"entity":"person","rows":"all"}],"kernel":"uk.stage.student_loans@1","mass":"conserve","outputs":[{"column":"student_loan_plan","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.100.0"],["policyengine-core","3.32.5"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"f2936c5e22a0e9b097437e3f3aabaf06c4561d5c25a9b7c05e720a6553f73bbc","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null}],"sources":[{"codec":"csv-tables","description":"Content-bound UK FRS and donor fixture/source bundle.","name":"frs"}]} diff --git a/test_support/microcosm_build/uk_spi_income.py b/test_support/microcosm_build/uk_spi_income.py index 970239fa8..94b45a97f 100644 --- a/test_support/microcosm_build/uk_spi_income.py +++ b/test_support/microcosm_build/uk_spi_income.py @@ -126,6 +126,8 @@ def _dead_support( "person_benunit_id": np.arange(201, 205, dtype="int64"), "age": [30, 40, 50, 60], "gender": ["MALE", "FEMALE", "MALE", "FEMALE"], + # Each one-person benefit unit is its own claimant. + "is_uc_claimant": np.ones(4, dtype=bool), } for position, column in enumerate(SPI_INCOME_IMPUTATION_COLUMNS, start=1): if column == drop_income_component: diff --git a/test_support/microcosm_build/uk_uc_capital_coherence.py b/test_support/microcosm_build/uk_uc_capital_coherence.py index 844d41f09..ac91f12dd 100644 --- a/test_support/microcosm_build/uk_uc_capital_coherence.py +++ b/test_support/microcosm_build/uk_uc_capital_coherence.py @@ -8,20 +8,30 @@ import pytest from microcosm.build.country_spec import load_country_spec +from microcosm.build.stochastic_assignment import stable_identity_uniforms from microcosm.build.uk_runtime.graph import uk_spine_graph from microcosm.build.uk_runtime.graph_kernels import UKStageKernel from microcosm.build.uk_runtime.national_frame import uk_national_frame from microcosm.build.uk_runtime.spi_support import support_channel_column from microcosm.build.uk_runtime.uc_capital_coherence import ( + UC_CAPITAL_COARSENING, + UC_CAPITAL_INCOME_BAND_EDGES, + UC_CAPITAL_MINIMUM_CELL_DONORS, UC_CAPITAL_REDRAW_OUTPUT, UC_CAPITAL_REDRAW_SALT, UC_CAPITAL_REDRAW_SEED, UKUCCapitalCoherenceStageTransform, _boolean_values, _dependent_children_band, - _redraw_spi_reporter_capital, + _household_to_benunit_weights, + _investment_income_band, + _redraw_spi_capital, cohere_uc_capital, ) +from microcosm.build.uk_runtime.uc_relationships import ( + UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS, + benunit_financial_investment_income, +) from microcosm.frame import WeightKind from microcosm.frame.adapters.policyengine_uk import PolicyEngineUKEngine from microcosm.graph.executor import _project_context @@ -85,6 +95,8 @@ def _frame(): } ) person = pd.concat([person, pd.DataFrame(other_members)], ignore_index=True) + for column in UC_FINANCIAL_INVESTMENT_INCOME_COLUMNS: + person[column] = 0.0 benunit = pd.DataFrame( { "benunit_id": [row[1] for row in rows], diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index fde303760..ac537fbd9 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -118,6 +118,9 @@ from microcosm.build.uk_runtime.spi_band_donors import ( UKSPIIncomeBandDonorStageTransform, ) +from microcosm.build.uk_runtime.spi_benefit_coherence import ( + UKSPIBenefitCoherenceStageTransform, +) from microcosm.build.uk_runtime.spi_housing_shell import ( UKSPIHousingShellStageTransform, ) @@ -160,11 +163,11 @@ _SPI_DONOR_SAMPLE_SIZE = 64 #: The packaged FRS spine roster the fixture exercises (manifest minus the #: certified-pair exclusions); moves whenever a spine stage is added. -UK_FIXTURE_STAGE_COUNT = 38 +UK_FIXTURE_STAGE_COUNT = 39 _QRF_ESTIMATORS = 4 # These are the complete object-string surface observed in the unchanged -# legacy 38-stage output. Graph storage uses pandas StringDtype/python. +# legacy 39-stage output. Graph storage uses pandas StringDtype/python. _NORMALIZED_STRING_COLUMNS: Mapping[str, tuple[str, ...]] = { "person": ( "gender", @@ -340,6 +343,11 @@ def _frs_tables() -> dict[str, pd.DataFrame]: "BEDROOM6": 1 + household_id % 4, "CTANNUAL": 900.0 + household_id * 10.0, "CTBAND": 1 + household_id % 7, + "CTDISC": 1 if household_id % 3 == 0 else 2, + "CT25D50D": ( + (2 if household_id % 9 == 0 else 1) if household_id % 3 == 0 else "" + ), + "CTREB": 1 if household_id % 3 or household_id % 7 == 0 else 2, "CTREBAMT": float(household_id % 3), "ADULTH": 1, "HRPNUM": 1, @@ -609,7 +617,7 @@ def _was_person_donor() -> pd.DataFrame: """Synthetic WAS round-8 persons of the 64 synthetic WAS households. Mixed-case raw names as in the deposit. Adults and dependent children per - household follow the household tab's NumAdultR8/NumCh18R8; Lifetime ISA + household follow the household tab's NumAdultR8/NumChildR8; Lifetime ISA holders are younger adults with small values (below the households' gross financial wealth, which WAS counts them in), one banded value, one ONS-imputed holder, one ONS-imputed non-holder, one self-employment @@ -689,6 +697,7 @@ def _was_donor() -> pd.DataFrame: # wealth covers the listed assets, and net is gross less the liabilities. main_residence = np.where(owner, 100_000.0 + rows * 2_000.0, 0.0) other_houses = np.where(position % 3 == 0, 1_000.0 + rows * 50.0, 0.0) + buy_to_let = np.where(position % 6 == 1, 40_000.0 + rows * 500.0, 0.0) buildings = np.where(position % 4 == 0, 3_000.0 + rows * 60.0, 0.0) land = np.where(position % 5 == 0, 10.0 + rows, 0.0) other_property = np.where(position % 7 == 0, 500.0 + rows * 5.0, 0.0) @@ -724,6 +733,7 @@ def _was_donor() -> pd.DataFrame: "DVLUKValR8_sum": land, "DVPropertyR8": main_residence + other_houses + + buy_to_let + buildings + land + other_property, @@ -735,7 +745,7 @@ def _was_donor() -> pd.DataFrame: "totalpenr8_aggr": 100.0 + rows * 10.0, "dvvaldbt_scaper8_aggr": 40.0 + rows, "NumAdultR8": 1 + position % 3, - "NumCh18R8": position % 3, + "NumChildR8": position % 3, "DVGIPPENR8_AGGR": 11.0 + rows, "DVGISER8_AGGR": 13.0 + rows, "DVGIINVR8_aggr": 15.0 + rows, @@ -743,7 +753,11 @@ def _was_donor() -> pd.DataFrame: "HBedRmR8": 1 + position % 5, "GORR8": np.take([8, 11, 12, 1], position % 4), "DVPriRntR8": private_rent, - "CTAmtR8": 900.0 + rows * 10.0, + "DVCTaxAmtAnnualR8": 900.0 + rows * 10.0, + # Net rent where the household holds property beyond its home. + "DVNetRentAmtAnnualR8_aggr": np.where( + (other_houses > 0.0) | (buy_to_let > 0.0), 2_000.0 + rows * 40.0, 0.0 + ), "HFINWNTR8_Sum": gross_financial - consumer_debt - student_loans, "HFINWNTR8_exSLC_Sum": gross_financial - consumer_debt, "HMortGR8": main_mortgage + other_mortgage, @@ -753,6 +767,7 @@ def _was_donor() -> pd.DataFrame: "HFINWR8_SUM": gross_financial, "DVhvalueR8": main_residence, "DVHseValR8_sum": other_houses, + "DVBltValR8_sum": buy_to_let, "DVBlDValR8_sum": buildings, "DVTotinc_bhcR8": 20_000.0 + rows * 1_000.0, "DVSaValR8_aggr": savings, @@ -1644,6 +1659,9 @@ def capture_root(frame: Frame) -> Frame: "uc_reporter_redraw": UKUCReporterRedrawStageTransform( stage=stages["uc_reporter_redraw"], engine=engine ), + "spi_benefit_coherence": UKSPIBenefitCoherenceStageTransform( + stage=stages["spi_benefit_coherence"], contract=contract + ), "uc_capital_coherence": UKUCCapitalCoherenceStageTransform( stage=stages["uc_capital_coherence"] ), @@ -1698,7 +1716,7 @@ def _run_legacy_plan( stages: Iterable[SourceStageSpec], implementations: Mapping[str, object], ) -> Frame: - """Run the legacy 38-stage StagePlan oracle and return its final frame.""" + """Run the legacy 39-stage StagePlan oracle and return its final frame.""" stages = tuple(stages) committed = load_country_spec("uk") diff --git a/tools/verify_uk_identity_stability.py b/tools/verify_uk_identity_stability.py index ff293b14b..d002afc04 100644 --- a/tools/verify_uk_identity_stability.py +++ b/tools/verify_uk_identity_stability.py @@ -531,7 +531,7 @@ def e7_identity_receipt( Not covered here, and deliberately so: - * the stage-1/stage-2 QRF fits and the dividend redraw, which twin-build + * the stage-1/stage-2 QRF fits, which twin-build determinism covers — the e6 and e8 precedent for QRF surfaces; * the ``employer_pension_contributions = 3 * employee_pension_contributions`` derive, which is a genuine E7 deterministic layer but which E8's @@ -670,8 +670,8 @@ def recompute(person_t, benunit_t, household_t) -> dict[str, pd.DataFrame]: entity: list(values.columns) for entity, values in original.items() }, "qrf_draw_columns_scope": ( - "excluded: the stage-1/stage-2 QRF fits and the dividend redraw " - "are covered by twin-build determinism (the e6 and e8 precedent)" + "excluded: the stage-1/stage-2 QRF fits are covered by twin-build " + "determinism (the e6 and e8 precedent)" ), "rewritten_layer_scope": ( "excluded: employer_pension_contributions = 3 x "