From f498924e8fd47d1eb8b237f8e783def8a5e7b24b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:59:10 +0100 Subject: [PATCH 01/19] Re-pin the UK Chronicle feed to 7846605 and vendor the bus journey, trip-rate and car-availability facts (#930 C2+C3) chronicle#274 landed as PolicyEngine/chronicle PR #275 (78466057): DfT BUS01 passenger journeys by area with the BUS01c concessionary split, the BUS05i operating-revenue and support components, NTS0303/NTS0601 trip rates by mode and age band, and the DfI full-fare concession journeys (277,183 rows, chronicle.consumer_fact.v3). No existing reference moves by value or period; the membership, census and validation-level surfaces move by their feed label only (631 active / 7 deferred / 8 signed out national; 20,885 active local; the parity receipts are byte-identical). Every vendored resource is regenerated with the new feed identity. Three are new: dft_bus_journeys.json (journeys and concessionary journeys for England, London, England outside London, the metropolitan split and the nine regions, FY2023-25; the seven BUS05i components; ONS mid-year population of the four countries and the nine English regions), nts_trip_rates.json and nts_car_availability.json; devolved_bus_finance.json gains the DfI concession journeys. The NTS0705a selection is pinned to its income-quintile groupby because the new NTS packages reuse the trip-rate concepts (it had grown from 24 to 84 rows). The new resources are declared in the country package and the frozen resource lists; their consumers are planned until the pricing and stage commits name them. Co-Authored-By: Claude Fable 5.1 --- .../930-chronicle-repin-7846605.changed.md | 1 + docs/uk-chronicle-feed-repin.md | 1 + .../microcosm/build/uk/chronicle_feed.json | 8 +- .../microcosm/build/uk/country_package.json | 15 + .../build/uk/desnz_domestic_energy_facts.json | 8 +- .../build/uk/devolved_bus_finance.json | 297 +- .../microcosm/build/uk/dft_bus_journeys.json | 8773 ++++++++++++ .../build/uk/dft_bus_value_anchors.json | 11 +- .../uk/ledger_fact_vendor_selections.json | 216 +- .../build/uk/licensed_cars_fuel_type.json | 8 +- .../uk/local_target_reference_membership.json | 2 +- .../build/uk/local_validation_levels.json | 61 +- .../microcosm/build/uk/need_energy_facts.json | 8 +- .../build/uk/nts_bus_use_frequency.json | 8 +- .../build/uk/nts_car_availability.json | 306 + .../microcosm/build/uk/nts_trip_rates.json | 4181 ++++++ .../build/uk/ofgem_price_cap_facts.json | 8 +- .../uk/ons_household_expenditure_facts.json | 8 +- .../microcosm/build/uk/orr_rail_facts.json | 8 +- .../microcosm/build/uk/qep_energy_prices.json | 8 +- .../microcosm/build/uk/road_fuel_anchors.json | 8 +- .../build/uk/target_reference_membership.json | 11393 +++++++--------- .../build/uk/uk_local_target_census.json | 104 +- .../tests/test_country_spec.py | 6 + .../tests/test_uk_chronicle_feed.py | 8 +- 25 files changed, 18886 insertions(+), 6569 deletions(-) create mode 100644 changelog.d/930-chronicle-repin-7846605.changed.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json create mode 100644 packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json create mode 100644 packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json diff --git a/changelog.d/930-chronicle-repin-7846605.changed.md b/changelog.d/930-chronicle-repin-7846605.changed.md new file mode 100644 index 000000000..6d8b211d8 --- /dev/null +++ b/changelog.d/930-chronicle-repin-7846605.changed.md @@ -0,0 +1 @@ +The UK Chronicle consumer feed is re-pinned to `PolicyEngine/chronicle` `78466057` (chronicle #274 via PR #275, the microcosm#930 landing: 277,183 rows, `chronicle.consumer_fact.v3`), which adds the DfT BUS01 local bus passenger journeys by area with the BUS01c concessionary split, the BUS05i operating-revenue and support components beyond fare receipts and net support, the NTS0303/NTS0601 trip rates by main mode and age band, and the DfI Northern Ireland full-fare concession journeys. No existing national or local reference moves by value or period: the membership, census and validation-level surfaces move by their feed label only (631 active / 7 deferred / 8 signed out national; 20,885 active local). Every vendored fact resource is regenerated with the new feed identity, and three are new: `dft_bus_journeys.json` (BUS01 journeys and concessionary journeys for England, London, England outside London, the metropolitan split and the nine English regions, years ending March 2023 to 2025; the seven BUS05i components; the ONS mid-year population of the four UK countries and the nine English regions, England being the regions' sum), `nts_trip_rates.json` (NTS0303 and NTS0601, 2023 to 2025) and `nts_car_availability.json` (NTS0205 England 2023 and 2024); `devolved_bus_finance.json` gains the DfI concession journeys. The NTS0705a selection in `dft_bus_value_anchors.json` is pinned to its household-income-quintile groupby because the new NTS packages reuse the two trip-rate concepts. diff --git a/docs/uk-chronicle-feed-repin.md b/docs/uk-chronicle-feed-repin.md index f0d82da3e..6c43f12ec 100644 --- a/docs/uk-chronicle-feed-repin.md +++ b/docs/uk-chronicle-feed-repin.md @@ -71,3 +71,4 @@ for England, Wales and Scotland (266,390 rows); the `ec20085` re-pin (#890 PR-S, The `c5e5bf8` re-pin (microcosm#725, chronicle #273, on top of `ec20085`) then brought the HMRC CGT Tables 7, 8 and 9 (asset type, residential property, carried interest), 276,205 rows, with no compiled value moving on either surface. +for England, Wales and Scotland (266,390 rows); the `ec20085` re-pin (#890 PR-S, chronicle #269/#270 via PR #271) brought the domestic energy facts the energy stage levels and prices against (DESNZ Energy Trends domestic consumption, subnational consumption and meter counts, QEP average prices paid, NEED 2024, ONS 04.5 sub-classes) and the census central-heating tables (275,698 rows). The `7846605` re-pin (microcosm#930, chronicle #274 via PR #275) brought the DfT BUS01 passenger and concessionary journeys by area, the BUS05i operating-revenue and support components, the NTS0303/NTS0601 trip rates by mode and age and the DfI full-fare concession journeys (277,183 rows), with the NTS0705a selection pinned to its quintile groupby because the new packages reuse the trip-rate concepts. diff --git a/packages/microcosm-build/src/microcosm/build/uk/chronicle_feed.json b/packages/microcosm-build/src/microcosm/build/uk/chronicle_feed.json index 83e8de39e..6a7d1807b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/chronicle_feed.json +++ b/packages/microcosm-build/src/microcosm/build/uk/chronicle_feed.json @@ -3,14 +3,14 @@ "country": "uk", "scope": "uk_calibration", "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", "consumer_fact_schema_versions": [ "chronicle.consumer_fact.v3" ], "consumer_fact_schema_sha256": "bdb51e2a8115634633ba7448c4005930fd9c0bfbade5e1b079b6bc24da485d3d", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" } diff --git a/packages/microcosm-build/src/microcosm/build/uk/country_package.json b/packages/microcosm-build/src/microcosm/build/uk/country_package.json index dd0ff27c1..da8e2e9e1 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/country_package.json +++ b/packages/microcosm-build/src/microcosm/build/uk/country_package.json @@ -391,6 +391,21 @@ "path": "ons_household_expenditure_facts.json", "kind": "legacy_json", "schema_id": "legacy_json" + }, + { + "path": "dft_bus_journeys.json", + "kind": "legacy_json", + "schema_id": "legacy_json" + }, + { + "path": "nts_trip_rates.json", + "kind": "legacy_json", + "schema_id": "legacy_json" + }, + { + "path": "nts_car_availability.json", + "kind": "legacy_json", + "schema_id": "legacy_json" } ] } diff --git a/packages/microcosm-build/src/microcosm/build/uk/desnz_domestic_energy_facts.json b/packages/microcosm-build/src/microcosm/build/uk/desnz_domestic_energy_facts.json index a3be7cd4b..50c10add8 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/desnz_domestic_energy_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/desnz_domestic_energy_facts.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json b/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json index 821b693e3..225dee5a2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json +++ b/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json @@ -3,7 +3,7 @@ "country": "uk", "kind": "uk_vendored_ledger_facts", "resource": "devolved_bus_finance.json", - "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets.", + "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets; DfI Northern Ireland Translink full-fare concession passenger journeys by fiscal year (the concessionary split for the Northern Ireland bus price).", "consumers": [ "uk_runtime.lcfs_consumption", "uk_runtime.etb_services" @@ -16,12 +16,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { @@ -72,10 +72,295 @@ "period_type": "fiscal_year" }, "row_count": 24 + }, + { + "label": "dfi_ni_translink_bus_full_fare_concession_journeys", + "selector": { + "source_name": "dfi_ni", + "source_concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "period_type": "fiscal_year" + }, + "row_count": 6 } ], - "row_count": 86, + "row_count": 92, "rows": [ + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_47761c17297570afa5f02bc0", + "semantic_fact_key": "ledger_semantic_fact_v2_6f5db9e2c98301d79066f6d1", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2019.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2019 + }, + "period_coverage": { + "start_date": "2019-04-01", + "end_date": "2020-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2019", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 10855000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_417e8b0e99c38d51a56fa733", + "semantic_fact_key": "ledger_semantic_fact_v2_6b83d6b89bb6a5d7dd58e9fe", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2020.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2020 + }, + "period_coverage": { + "start_date": "2020-04-01", + "end_date": "2021-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2020", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 3500000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b957e464f7b52b76cd3d2aad", + "semantic_fact_key": "ledger_semantic_fact_v2_953236ab76764c187a659764", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2021.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2021 + }, + "period_coverage": { + "start_date": "2021-04-01", + "end_date": "2022-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2021", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 6179000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ed9db21da5f78c78cf019fce", + "semantic_fact_key": "ledger_semantic_fact_v2_1ea56ff6e7b12cdc6cb046f6", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2022.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2022 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2022", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 7824000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_214ea2754f799551cac9b76d", + "semantic_fact_key": "ledger_semantic_fact_v2_4a4392f37ec385faf43359bd", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2023.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2023", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 8642000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_58c1c16649823db6022568d4", + "semantic_fact_key": "ledger_semantic_fact_v2_18530dd75bc0c9806fb44d86", + "source_record_id": "dfi_ni.public_transport.figure_6.fy2024.full_fare_concession.passenger_journeys", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "translink_bus_passenger" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dfi_ni.public_transport.figure_6.fy2024", + "groupby_dimension": "dfi_ni.travel_status", + "groupby_value_id": "full_fare_concession", + "table_record_kind": "detail" + }, + "dimensions": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "source": { + "source_name": "dfi_ni", + "source_table": "Public Transport Statistics Northern Ireland 2024-25 Figure 6", + "source_file": "public-transport-statistics-2024-25.xlsx", + "source_sha256": "8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca", + "vintage": "2024_25", + "raw_r2_key": "raw/dfi_ni/dfi-ni-public-transport-statistics-2024-25/2025/8e0a0f14410a25f16a13b26d312cfd4e3dac55129ed0c541165679aaa9fcd6ca/public-transport-statistics-2024-25.xlsx" + }, + "value": 8960000 + }, { "aggregate_fact_key": "ledger_aggregate_fact_v2_288b81ee8cbcfdfa95bc22cf", "semantic_fact_key": "ledger_semantic_fact_v2_df8a2df5fa3eca57cce2b853", diff --git a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json new file mode 100644 index 000000000..4414145f0 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json @@ -0,0 +1,8773 @@ +{ + "schema_version": 1, + "country": "uk", + "kind": "uk_vendored_ledger_facts", + "resource": "dft_bus_journeys.json", + "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.lcfs_consumption", + "uk_runtime.etb_services", + "uk_runtime.bus_fare_pricing" + ], + "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", + "generator": { + "tool": "tools/vendor_uk_ledger_facts.py", + "version": 1 + }, + "source_fact_feed": { + "source_repo": "PolicyEngine/chronicle", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", + "build": "build-bundle --suite uk -> build-consumer-artifact", + "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" + }, + "selections": [ + { + "label": "bus01a_passenger_journeys_by_area", + "selector": { + "source_name": "dft", + "source_concept": "dft.local_bus_passenger_journeys", + "period_type": "fiscal_year", + "period_value": [ + "2023", + "2024", + "2025" + ], + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london", + "dft:english_metropolitan_areas", + "dft:english_non_metropolitan_areas", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimensions": [] + }, + "row_count": 39 + }, + { + "label": "bus01c_concessionary_journeys_by_area", + "selector": { + "source_name": "dft", + "source_concept": "dft.local_bus_passenger_journeys", + "period_type": "fiscal_year", + "period_value": [ + "2023", + "2024", + "2025" + ], + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london", + "dft:english_metropolitan_areas", + "dft:english_non_metropolitan_areas", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimension_values": { + "journey_category": [ + "elderly_disabled_concessionary", + "total_concessionary" + ] + } + }, + "row_count": 78 + }, + { + "label": "bus05i_revenue_and_support_components", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.local_bus_concessionary_travel_reimbursement", + "dft.local_bus_bus_service_operators_grant", + "dft.local_bus_gross_public_transport_support", + "dft.local_bus_net_public_transport_support", + "dft.local_bus_total_estimated_operating_revenue", + "dft.local_bus_additional_funding_to_operators", + "dft.local_bus_fare_cap" + ], + "period_type": "fiscal_year", + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london" + ] + }, + "row_count": 54 + }, + { + "label": "ons_mid_year_population_countries_and_english_regions", + "selector": { + "source_name": "ons", + "source_concept": "ons.mid_year_population_estimate", + "period_type": "calendar_year", + "geography_id": [ + "K02000001", + "S92000003", + "W92000004", + "N92000002", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimensions": [] + }, + "row_count": 26 + } + ], + "row_count": 197, + "rows": [ + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5690b4c2061f2a38249c30d6", + "semantic_fact_key": "ledger_semantic_fact_v2_7d25a88459270a5892afc20d", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 152842537 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cedf531f21446c352290e3b7", + "semantic_fact_key": "ledger_semantic_fact_v2_d7d967f3bdcd9dcb6385cf8f", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 205774181.94 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_38ffdff9d554f39ad819e474", + "semantic_fact_key": "ledger_semantic_fact_v2_e975f3fdbb0ef39ffe13f040", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 84539980.19 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_eb69f5df37c57c938891e409", + "semantic_fact_key": "ledger_semantic_fact_v2_5fd2422d510aca07024ab78a", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england_outside_london.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 152842537 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1dd11254322eacb86ed152a5", + "semantic_fact_key": "ledger_semantic_fact_v2_1b186c8b3c1ab151ccd10db7", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england_outside_london.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 205774181.94 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4c0066fd9c1d82be96b72fd5", + "semantic_fact_key": "ledger_semantic_fact_v2_ea2ce5844584c9bdbd233f3c", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england_outside_london.additional_funding_to_operators", + "concept": "dft.local_bus_additional_funding_to_operators", + "measure_id": "additional_funding_to_operators", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 84539980.19 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_912897a280c8279d662e1e5f", + "semantic_fact_key": "ledger_semantic_fact_v2_a4df9df1f725fa6f920e420e", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 200492643.10000002 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_61cb62f5a76864b9007701f7", + "semantic_fact_key": "ledger_semantic_fact_v2_01ec07ef9ccf59cefcb0fcc4", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 209670352.2 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_46b3743626f4382a99ecf5db", + "semantic_fact_key": "ledger_semantic_fact_v2_679659a46c816a1d1c7908a1", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 199490000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5e0e0e3df357b26e40069e78", + "semantic_fact_key": "ledger_semantic_fact_v2_e28d7f381e6fe3ece61c4c2e", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england_outside_london.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 200492643.10000002 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_60a3f4e2d46db42110b71fca", + "semantic_fact_key": "ledger_semantic_fact_v2_0f273941b8978aeeaee754be", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england_outside_london.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 209670352.2 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ecad41cd51caeef445e1a2e1", + "semantic_fact_key": "ledger_semantic_fact_v2_83fd63b303cd7774dc201600", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england_outside_london.bus_service_operators_grant", + "concept": "dft.local_bus_bus_service_operators_grant", + "measure_id": "bus_service_operators_grant", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.bus_service_operators_grant.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 199490000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_25e18aaf6455c714d6d27f49", + "semantic_fact_key": "ledger_semantic_fact_v2_41b37bd3244d9a837c730b74", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 140342000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8d93e930beaef807ddb2405e", + "semantic_fact_key": "ledger_semantic_fact_v2_74205d5b15f52f568fd43df9", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 147066918.7 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_2c493e2b4289baae63964517", + "semantic_fact_key": "ledger_semantic_fact_v2_06925591c328953d51887126", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 183343000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_befd1cd488fdd9b12e01bf47", + "semantic_fact_key": "ledger_semantic_fact_v2_8531b88fe374b9c470a5c21f", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 722024614.14 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_248ff7b4afe2b2a64808fcde", + "semantic_fact_key": "ledger_semantic_fact_v2_f41b606a57ddd673e4e22769", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 754380441.0400001 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e5c94ef04c233920a63e204e", + "semantic_fact_key": "ledger_semantic_fact_v2_43705086afb1e12b5cc24635", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 813987124.0500001 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3085c4f04930277d1381132d", + "semantic_fact_key": "ledger_semantic_fact_v2_e5812bea96c4ffd28516b68b", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england_outside_london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 581682614.1400001 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d5a0c2682d3c48652b1e6ac4", + "semantic_fact_key": "ledger_semantic_fact_v2_dcba629385bc078f2a5e1d35", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england_outside_london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 607313522.3399999 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b20602c5dc5582de24b7f35b", + "semantic_fact_key": "ledger_semantic_fact_v2_730fbd804c059d760e5a6f55", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england_outside_london.concessionary_travel_reimbursement", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "measure_id": "concessionary_travel_reimbursement", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 630644124.05 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_09eb9aeaf57b40b342201ce0", + "semantic_fact_key": "ledger_semantic_fact_v2_b17f9a2ffe341f8585fe71c0", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 60183971.36 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e96ede4caa1a3531e220e7a1", + "semantic_fact_key": "ledger_semantic_fact_v2_dbe78afc6b4b08d015ed77f9", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 278951028.5 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_870677d5b0716a1ac6a7823f", + "semantic_fact_key": "ledger_semantic_fact_v2_bbc75819adbc358f6143fe68", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 515693216.6 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_93ef83f54ac73e774b967b4c", + "semantic_fact_key": "ledger_semantic_fact_v2_0bf485f26840b3458530fb41", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england_outside_london.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 60183971.36 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ff2cf618b9b385cb83585237", + "semantic_fact_key": "ledger_semantic_fact_v2_c5aced203708568ecc4cf3da", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england_outside_london.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 278951028.5 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b7e89fd76da945525b3d3d4f", + "semantic_fact_key": "ledger_semantic_fact_v2_74758d2bb49e52a29b4f0477", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england_outside_london.fare_cap", + "concept": "dft.local_bus_fare_cap", + "measure_id": "fare_cap", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.supplemental_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 515693216.6 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e6f609986ec9b0fbb51e229b", + "semantic_fact_key": "ledger_semantic_fact_v2_837ac03cf0a5cda7e19c0b0a", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023.london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 797698000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e298d92c481566821b0863c8", + "semantic_fact_key": "ledger_semantic_fact_v2_2e9e9d1fbc2a86f2b888dcb5", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024.london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 807340000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_079b83135c4909192b5fabd4", + "semantic_fact_key": "ledger_semantic_fact_v2_92aee490753cd229b1ebccef", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025.london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 946871000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0e2e0a61da3bf91d52a689b8", + "semantic_fact_key": "ledger_semantic_fact_v2_a14dff9fe05b5cdd194d7dec", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023.england.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1272972000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0cd9783ce82f50be0f9ffb6c", + "semantic_fact_key": "ledger_semantic_fact_v2_e6817e5dd7efbcd6926b9085", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024.england.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1371771000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a379550c46e7b8bcd179b1dd", + "semantic_fact_key": "ledger_semantic_fact_v2_56e2d19d71d5295650a198ee", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025.england.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1584976000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f02246b67fb98fde54b58aab", + "semantic_fact_key": "ledger_semantic_fact_v2_ba9e02fd4a895252edb5dc70", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023.england_outside_london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 475274000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_883dfcd89418a145f395787f", + "semantic_fact_key": "ledger_semantic_fact_v2_9e168f66881364476eacea62", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024.england_outside_london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 564431000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_68942a6311821f162c1dde17", + "semantic_fact_key": "ledger_semantic_fact_v2_0de48bdec09e11563de4e62d", + "source_record_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025.england_outside_london.gross_public_transport_support", + "concept": "dft.local_bus_gross_public_transport_support", + "measure_id": "gross_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_public_transport_support.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 638105000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_607ba1f8722696058a260601", + "semantic_fact_key": "ledger_semantic_fact_v2_bb546c50a348d7d17a1fe7dd", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 797698000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cc5dc4683fdb77cc0282b75b", + "semantic_fact_key": "ledger_semantic_fact_v2_4d2286f9fb99e2bd25e5fac7", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 807340000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fbebb848e06c38c9def1fe48", + "semantic_fact_key": "ledger_semantic_fact_v2_bdf51179023ba9314d35300d", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 946871000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c5303a06cb75391e477ab167", + "semantic_fact_key": "ledger_semantic_fact_v2_33f4313051dd98d11aac8ab1", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1112341000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c21c03964ca6e373363d2cd0", + "semantic_fact_key": "ledger_semantic_fact_v2_7e94cf348a0bfca51d087d1f", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1202945000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_05dba09124d77141e3f84add", + "semantic_fact_key": "ledger_semantic_fact_v2_b5511563f74257716d9cfdb4", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 1411194000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_921feab05a616560cb749c5c", + "semantic_fact_key": "ledger_semantic_fact_v2_ba6b58c44a22725c8bb60a1e", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2023.england_outside_london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 314643000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a9cbe5c19b617ac1da890584", + "semantic_fact_key": "ledger_semantic_fact_v2_5cfba6d596db51de89bc1013", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2024.england_outside_london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 395605000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_05051b19ca91463630020d74", + "semantic_fact_key": "ledger_semantic_fact_v2_35195e55df67ce6fac2dc060", + "source_record_id": "dft.bus05i.bus05bi.support_components.fy2025.england_outside_london.net_public_transport_support", + "concept": "dft.local_bus_net_public_transport_support", + "measure_id": "net_public_transport_support", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05bi.support_components.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 464323000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d736e2bcff5037dccf3bcc8c", + "semantic_fact_key": "ledger_semantic_fact_v2_152bd4e960c8ffc2eaa3ee15", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 38899143.05022 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0a043d3a57a2fab5f6297995", + "semantic_fact_key": "ledger_semantic_fact_v2_fc678b4146759c4ab384a23f", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 45825388.91603 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8ddefce8760dc99958a61731", + "semantic_fact_key": "ledger_semantic_fact_v2_1acb404501a8f1b9ab9332fb", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 130232701.57689 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7bd553b8eca37a2d5fcbdc26", + "semantic_fact_key": "ledger_semantic_fact_v2_65ed9328ac785856dd41ddab", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 36881127.47965 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_288f43299cd218a424705d41", + "semantic_fact_key": "ledger_semantic_fact_v2_74c3a555e9ae492ad8697d86", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 46266820.62044 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0e347504e174d1623db138e1", + "semantic_fact_key": "ledger_semantic_fact_v2_2b40f71dbd3415716296679e", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 130338359.53759001 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b6fb83f610a788a80a226fee", + "semantic_fact_key": "ledger_semantic_fact_v2_f421d9db98c472507baed836", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 38453931.1965 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0c6da5c5ea0a42eb31f6ae94", + "semantic_fact_key": "ledger_semantic_fact_v2_480864bf5bec5ca46486f7b5", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 50732890.046500005 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f729e9d184fd2b42da69c7e8", + "semantic_fact_key": "ledger_semantic_fact_v2_4d8eaa33f05a231a365bff73", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.north_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 139215323.89253 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_deb16cd92c173a31aa2b0f8e", + "semantic_fact_key": "ledger_semantic_fact_v2_ade3df06bd8aa7c6975c0c42", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 69412278.70917 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c06299e6804e0b0b68aab1af", + "semantic_fact_key": "ledger_semantic_fact_v2_4c31b1b5d1552635f09b6e21", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 105729248.94121 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8c81c4fd790479adeac22c40", + "semantic_fact_key": "ledger_semantic_fact_v2_8c5078d1cb3f85611906355d", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 298575757.8268 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d154988e5554f6be97596d1d", + "semantic_fact_key": "ledger_semantic_fact_v2_48c5c26d3cd3a4cf0b8b345c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 72245682.55333 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b8a35162b02c81f75e1d1e11", + "semantic_fact_key": "ledger_semantic_fact_v2_40fdb313653bba3fd2eb48c1", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 114564908.25082 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_45197e51027b6a5dc5238221", + "semantic_fact_key": "ledger_semantic_fact_v2_2c0035a0de9ff1ce1bc6a318", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 324468146.15824 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1fedde92721dcd600311a56d", + "semantic_fact_key": "ledger_semantic_fact_v2_fc724c9b99c1406e71a1a1a1", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 73922959.04414 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_022e44e61e4cf1a872903ff8", + "semantic_fact_key": "ledger_semantic_fact_v2_c3f039a84008d4ef530805bc", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 111529764.84425 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_2141b3580d89d6e580c065b9", + "semantic_fact_key": "ledger_semantic_fact_v2_d598bd6638473c7b1104464d", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.north_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "north_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 339352717.50098 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_61954ae9c6caf567bfa7bbed", + "semantic_fact_key": "ledger_semantic_fact_v2_abca4c9f9440f602f5b659be", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 49939448.44951 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d3e592b34b682088207987bc", + "semantic_fact_key": "ledger_semantic_fact_v2_3a11f1a10083f10a8a8362b9", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 70664146.40951 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_94d509068cf4a62924a27e5d", + "semantic_fact_key": "ledger_semantic_fact_v2_106e9733669a652fdd0447e5", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 222044737.64956 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7b9dd5aa2457a9b23b36d649", + "semantic_fact_key": "ledger_semantic_fact_v2_ed18a784ad13f5d3d7b34574", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 53280680.614029996 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e9aea9ee044cd9a0c2ffdc8e", + "semantic_fact_key": "ledger_semantic_fact_v2_63b1d04e46bac94c4c9fb99b", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 74407487.46899 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_27d8a7cb1d7036cb6cfddcd9", + "semantic_fact_key": "ledger_semantic_fact_v2_0d183831461ca36cb4a7abed", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 236760176.99289 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_2ee677980766174bef68fad7", + "semantic_fact_key": "ledger_semantic_fact_v2_c4048a345da918a60969fee0", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 53725164.34659 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ac419b6ff4c08621fcd6c167", + "semantic_fact_key": "ledger_semantic_fact_v2_115b2eba50e52ac9cf762dd7", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 73956497.39659 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_914b4aa7a302ca75184bc55f", + "semantic_fact_key": "ledger_semantic_fact_v2_844ac41cdeb80f2f75372648", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.yorkshire_and_the_humber.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "yorkshire_and_the_humber", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 236203795.62029 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4eee0da5323bf4217f6fd00f", + "semantic_fact_key": "ledger_semantic_fact_v2_9e1ac855a0f1f697e87f3f9c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 32714673.85494 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_52ef82d90ab80be7fcfcaa74", + "semantic_fact_key": "ledger_semantic_fact_v2_834296c5f51f0f8ee599dd1e", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 35530981.83865 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5828ad7eec15802955f29bcd", + "semantic_fact_key": "ledger_semantic_fact_v2_aa255b438e3352838e604dea", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 142443312.18285 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7524c8ecd1a998dbb2c2df21", + "semantic_fact_key": "ledger_semantic_fact_v2_20ffebf0ccb72ed40b808b49", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 35920658.98549 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7fecd988ade379135ab75da2", + "semantic_fact_key": "ledger_semantic_fact_v2_8e028213ceff6b3139738b84", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 38790111.94748 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5a13ebfd574b93cc57d1646d", + "semantic_fact_key": "ledger_semantic_fact_v2_7df5b20d202dbf1b38781756", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 161028194.53840998 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_649dab0be2b7677d078deb55", + "semantic_fact_key": "ledger_semantic_fact_v2_3ea4639994e586fba534e70b", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 36770099.993540004 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_abd93b9dc54ca194b2219cd4", + "semantic_fact_key": "ledger_semantic_fact_v2_804ea681eb3de6162ec21e52", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 39479251.99354 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_34838f992e9c421d7f612e60", + "semantic_fact_key": "ledger_semantic_fact_v2_f88a9dd728c68c8cfb0de625", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.east_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 163902020.46597 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_439103867b607f2af27dc355", + "semantic_fact_key": "ledger_semantic_fact_v2_db23d0fd168db17fe14f9e9c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 47418317.36733 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1d818a731f6ed1501f3b6360", + "semantic_fact_key": "ledger_semantic_fact_v2_a09dfaba0aa9fa9b662916ad", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 67059664.61086 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c6e89fb035444339961eb1d0", + "semantic_fact_key": "ledger_semantic_fact_v2_ce8ac6cd9923203f49cb7172", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 255956272.20091 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_34fd98c05b054e2b150baef7", + "semantic_fact_key": "ledger_semantic_fact_v2_b8a6fabd01069ff57d79ba14", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 49290189.79172 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f339cdccd46842f19679de3e", + "semantic_fact_key": "ledger_semantic_fact_v2_9f6621ca7023eaa5a269b650", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 68718816.49157 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3615817a48ea3eaeef1118aa", + "semantic_fact_key": "ledger_semantic_fact_v2_2ca3f8adaf388b0124b6aba0", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 282543066.68100005 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_125612b37616cd5fbb1c1567", + "semantic_fact_key": "ledger_semantic_fact_v2_1e687285de7639a116729a19", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 50234865.759670004 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a8c772099b35d7dff2272ff5", + "semantic_fact_key": "ledger_semantic_fact_v2_526a3eb8f2548c2c5b6b9ef8", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 74515157.86493 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fd4192304b8225e79d6847cb", + "semantic_fact_key": "ledger_semantic_fact_v2_4c760820d925123e397b4726", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.west_midlands.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "west_midlands", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 295332910.62634 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_840b7123c253f114297210e5", + "semantic_fact_key": "ledger_semantic_fact_v2_eb18383136092e68a9004d29", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 31840966.08391 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a228db981ef5543c64b76103", + "semantic_fact_key": "ledger_semantic_fact_v2_d1dd979d6fa31c297afd9cbd", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 36043127.71608 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_00b482d0aa21325c77d6fc3d", + "semantic_fact_key": "ledger_semantic_fact_v2_c15f0b84045d4a53f41beed0", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 141239787.68541 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b478001075d8fb5cc117bd00", + "semantic_fact_key": "ledger_semantic_fact_v2_5f002939459765e3ab9478b9", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 34637575.636599995 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1241a3e4d0c4dd4650448664", + "semantic_fact_key": "ledger_semantic_fact_v2_56cec82b502a91c132241a2b", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 37236911.31346 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fd041bc77589a0eb0e920cca", + "semantic_fact_key": "ledger_semantic_fact_v2_585bc713c7d71fb4efe2ef9a", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 155660335.33314002 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e1632c2f1db50584c9dfa1f5", + "semantic_fact_key": "ledger_semantic_fact_v2_525389e4b37d3627355f6805", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 35679050.53577 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_479de7a80a738e5cef1d73fd", + "semantic_fact_key": "ledger_semantic_fact_v2_453381557057c5a3286aa0db", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 40273483.782630004 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_df157c32fd1f43f1f188a55a", + "semantic_fact_key": "ledger_semantic_fact_v2_25c14abe65db97831fd06445", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.east_of_england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "east_of_england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 161939341.50538 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3d16e8cb0edcb8bb7b78d6b6", + "semantic_fact_key": "ledger_semantic_fact_v2_a29b13e6761c5c3015338f6d", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 199698780.41383 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_399b33d0fb49982e157f1537", + "semantic_fact_key": "ledger_semantic_fact_v2_bb615efdc6363b23b0f275aa", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 506313778.42527 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fd20d0c656fd031d73402057", + "semantic_fact_key": "ledger_semantic_fact_v2_f451805e37cfc27b6c0e0559", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1766130759.74 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3f5817a893091b3233d40b12", + "semantic_fact_key": "ledger_semantic_fact_v2_dbeac3d59da16045eb13370c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 215347347.34692 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_273d2fa1fe2ae6bf66892c39", + "semantic_fact_key": "ledger_semantic_fact_v2_8c3628224822f0676d3ac708", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 518934321.13032997 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_69c422ad7bdb67bd03c12f4c", + "semantic_fact_key": "ledger_semantic_fact_v2_91ba89ffc133e12a27a1be59", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1848498990.49 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7d3ff84a5654de54ea866a11", + "semantic_fact_key": "ledger_semantic_fact_v2_05057316b5d1a530a5288a25", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 222979957.78748 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8df4f7a483dcfb50005f3e07", + "semantic_fact_key": "ledger_semantic_fact_v2_a8818228a86ffc968c022054", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 497523765.08908 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_56195cb6235aeccc8b72cb21", + "semantic_fact_key": "ledger_semantic_fact_v2_f88acaf293a3e945bc9fb09f", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1821485000 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_72145318216d3656a8f578ab", + "semantic_fact_key": "ledger_semantic_fact_v2_a327f5694d7453aa50f59150", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 62203907.64413 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3140ddc7133042a51af6f274", + "semantic_fact_key": "ledger_semantic_fact_v2_4d2447e07b0eddf8ba2e4196", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 73202137.23535 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_790f0dc90361910902859b7d", + "semantic_fact_key": "ledger_semantic_fact_v2_a0f60ddc916da274966e9cd5", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 274269981.44747 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8100127a51cdc80ff621e33c", + "semantic_fact_key": "ledger_semantic_fact_v2_204e1a0544a06541bd24cab5", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 67780572.97149 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_babff4be85e8a9be475f6a2f", + "semantic_fact_key": "ledger_semantic_fact_v2_3cf245eb39baeaad6cf9a71e", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 78734924.72384 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_89b4874b734b9f8e91f9bceb", + "semantic_fact_key": "ledger_semantic_fact_v2_b40da584c213bbb23e282b18", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 307485426.81548005 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7b088b944c8e6729b9440743", + "semantic_fact_key": "ledger_semantic_fact_v2_04ab41325b56f05d0c2266db", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 70268290.35276 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_41a2646cd9afda82bfd6e405", + "semantic_fact_key": "ledger_semantic_fact_v2_0c1933c7cf81f1a2a5c5ce96", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 84791906.74958 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d9406a1b16c75ba1b900d3d0", + "semantic_fact_key": "ledger_semantic_fact_v2_4944a56e4a55451005ccbb9f", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.south_east.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_east", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 322147459.66648 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_df79d965a03134efe431aab7", + "semantic_fact_key": "ledger_semantic_fact_v2_d45a7222567344feb32c757f", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 36398273.95865 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_622753b22791bd450d593f9f", + "semantic_fact_key": "ledger_semantic_fact_v2_e0fc93109d1bc60f8d944926", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 36680568.78496 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_84b551476c6ed13daa4b265a", + "semantic_fact_key": "ledger_semantic_fact_v2_71b02b42f81f939b87c4ffc4", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 158079092.45496002 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_95e9dbcc9f8d8bdcd8bf744d", + "semantic_fact_key": "ledger_semantic_fact_v2_650873c7596f9445b0d9cca4", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 40980661.34208 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b57fda82ca43cffe12bf0761", + "semantic_fact_key": "ledger_semantic_fact_v2_c68e3738e1e78547a419b04a", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 41010101.29849 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8ad85cf2a6a5e6d860829e9e", + "semantic_fact_key": "ledger_semantic_fact_v2_d8d192faa2edd4776156cde3", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 182629193.95961002 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6eddf7c64024ce6ab40cb2dc", + "semantic_fact_key": "ledger_semantic_fact_v2_f64a7407759f9c8df9d1e4db", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 43791988.916420005 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5eec7b05f66a1bedc14c85f2", + "semantic_fact_key": "ledger_semantic_fact_v2_0c8e5ecfd245a415dc8caada", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 43828655.91642 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f01a441c6130ef2fd5e4f0c0", + "semantic_fact_key": "ledger_semantic_fact_v2_896bee51a887431324fbbdc9", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.south_west.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "south_west", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 192416317.98334 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c4761681baeacb7cca39cd5e", + "semantic_fact_key": "ledger_semantic_fact_v2_2eb78b40d6aec4d8ac1697eb", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 568525789.53169 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f75f695d8d37eeb6edf31892", + "semantic_fact_key": "ledger_semantic_fact_v2_6994c0c8542f1fd0d71573e2", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 977049042.87792 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cd4fe01ecf39ab0a5e793a8b", + "semantic_fact_key": "ledger_semantic_fact_v2_c323a1bc4a43003f831369db", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 3388972402.76485 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b21bb3808d4271872bea7986", + "semantic_fact_key": "ledger_semantic_fact_v2_8e299022ff615a62d11e72b0", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 606364496.72131 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f5db8984e72c9527b8ed7d44", + "semantic_fact_key": "ledger_semantic_fact_v2_a2b843830d1aa8980d5e4b8c", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1018664403.24542 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_41e57f7928a33858673448b2", + "semantic_fact_key": "ledger_semantic_fact_v2_631b0e568a205664460371e7", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 3629411890.50636 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_17fb561f742bd528847ed360", + "semantic_fact_key": "ledger_semantic_fact_v2_35f125991dc901b2a256428c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 625826307.93287 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e9fefef6ad214021c559648e", + "semantic_fact_key": "ledger_semantic_fact_v2_fd89fb67f28a86a0864d00d9", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1016631373.68352 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_54b765700df55e4e82a6d6a9", + "semantic_fact_key": "ledger_semantic_fact_v2_6c93132b530fd866043faca2", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.england.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 3671994887.26131 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_85bfb25c9ba7c6d90fc4ae97", + "semantic_fact_key": "ledger_semantic_fact_v2_02a1348b2cd49b192f904b50", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 368827009.11785996 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_bdcca6fa3753bc99deee65b3", + "semantic_fact_key": "ledger_semantic_fact_v2_26ebeef21adad52735cd2f5f", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 470735264.45264995 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c2f74635788831750afbd14c", + "semantic_fact_key": "ledger_semantic_fact_v2_a574bfb34af8e2751d1dc7f6", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1622841643.0248501 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_745d802b08ab263e1eb42c9f", + "semantic_fact_key": "ledger_semantic_fact_v2_1a44ec80eed1f805a665c1b0", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 391017149.37439 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_28d54697cb6d070cb45762ab", + "semantic_fact_key": "ledger_semantic_fact_v2_1d8647b6b4b12bc4785efa21", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 499730082.11509 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3d2ba16a1ded87565a992184", + "semantic_fact_key": "ledger_semantic_fact_v2_8b749be6b51300e814df6724", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1780912900.01636 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_02381ef193ba9dc6fda0bc13", + "semantic_fact_key": "ledger_semantic_fact_v2_586ec6ffc89b085b821036f2", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 402846350.14539 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7d9165a26ee135ec979dce8f", + "semantic_fact_key": "ledger_semantic_fact_v2_dcb4044054ea556776c3392f", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 519107608.59444 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a629c2b2e3b509e0490a9dfe", + "semantic_fact_key": "ledger_semantic_fact_v2_aeef658b71b1f694bf10d2c0", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.england_outside_london.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1850509887.26131 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ad70ae5683c810488a097b33", + "semantic_fact_key": "ledger_semantic_fact_v2_5720df29ed22c035bd32a68f", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 143315226.58351 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b3171b48f0d581ba537b28e0", + "semantic_fact_key": "ledger_semantic_fact_v2_fac67ee4310b08c2f27d383f", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 218412570.50822 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4610ac3605be0fef5a051a61", + "semantic_fact_key": "ledger_semantic_fact_v2_92ff83b422d6d15e71b3f625", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 689750140.52922 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_2ce973172177b8fa4e68ba3f", + "semantic_fact_key": "ledger_semantic_fact_v2_7608827dfee30cb8244ee4f2", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 147721448.76997 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_51bc5970f332cc26cf83ab94", + "semantic_fact_key": "ledger_semantic_fact_v2_e3b0b1048373a733b3078afe", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 231895407.91466 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6252706f83ed74f22abbe2ea", + "semantic_fact_key": "ledger_semantic_fact_v2_c968050203eadf9d142d829e", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 741448933.7232 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cf7ead8532da3799c7995c1a", + "semantic_fact_key": "ledger_semantic_fact_v2_732cebedd388c5f5b7eba7c5", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 151467312.13606 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f4258ec5dc1dd177d3f7beff", + "semantic_fact_key": "ledger_semantic_fact_v2_af2e312fca7f850cdf5e786a", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 237993796.60283 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7afdeb3ba448b85b8d19b054", + "semantic_fact_key": "ledger_semantic_fact_v2_1f8cde5ab2494d0c20a66917", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.english_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 776594432.4191599 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d7940c9e56363ce999fdf5ae", + "semantic_fact_key": "ledger_semantic_fact_v2_c98aa5f1ca3c101625f51ce7", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 225511782.53435 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3065538eb4e5cf2bba505ab7", + "semantic_fact_key": "ledger_semantic_fact_v2_bddb15d756e94d2e1a3c477d", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2023.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 252322693.94443 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_49eac01f59c504f41577e910", + "semantic_fact_key": "ledger_semantic_fact_v2_0592bdf35fb65954bc0d7bfb", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2023.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 933091502.49563 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3bea312338b7b2c8ca332552", + "semantic_fact_key": "ledger_semantic_fact_v2_7da35d6d1afcb091cd648afe", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 243295700.60442 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_74791856944e90524e6b1081", + "semantic_fact_key": "ledger_semantic_fact_v2_504a10336cab6ff3c3e634a2", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2024.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 267834674.20043 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6170f179d9aae401fa0ffff1", + "semantic_fact_key": "ledger_semantic_fact_v2_b747c5382a7a3bb7339295c3", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2024.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1039463966.29316 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a1467f4541768677c3bf75a1", + "semantic_fact_key": "ledger_semantic_fact_v2_5bf3981f6b051e0f95e2271c", + "source_record_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.elderly_disabled_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "elderly_disabled_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 251379038.00933 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6fc604753e6b9a7edd49c047", + "semantic_fact_key": "ledger_semantic_fact_v2_4fc5b705f1fd981256c4f326", + "source_record_id": "dft.bus01.bus01c.total_concessionary.fy2025.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01c.total_concessionary.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": { + "journey_category": "total_concessionary" + }, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 281113811.99161005 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8d0c83bd837acf06d025db7f", + "semantic_fact_key": "ledger_semantic_fact_v2_efd5c909460e9bc556e7a366", + "source_record_id": "dft.bus01.bus01a.passenger_journeys.fy2025.english_non_metropolitan_areas.passenger_journeys", + "concept": "dft.local_bus_passenger_journeys", + "measure_id": "passenger_journeys", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "bus_passenger" + }, + "geography": { + "id": "dft:english_non_metropolitan_areas", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus01.bus01a.passenger_journeys.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "english_non_metropolitan_areas", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS01a passenger journeys and BUS01c concessionary passenger journeys", + "source_file": "bus01.ods", + "source_sha256": "51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8", + "vintage": "bus_statistics_2025_revised_2026_03_24", + "raw_r2_key": "raw/uk/dft/dft-bus01-passenger-journeys-2025/2025/51b5aa5e5e2113c9376ed63071891e144421ed205c60cb94e1eb0d723ac0f9c8/bus01.ods" + }, + "value": 1073915454.84215 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8fc779aa8022ee8a547aa945", + "semantic_fact_key": "ledger_semantic_fact_v2_9a0a32c5e42ce6a0e65c47a3", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023.london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 2150105129.25873 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8101b27a2a1b35f8d60514c9", + "semantic_fact_key": "ledger_semantic_fact_v2_e54855b67d1307df7558cfb0", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024.london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 2296494561.03642 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6319a4df68f916b8399f2de4", + "semantic_fact_key": "ledger_semantic_fact_v2_186662cb6a62b432c6b2ad2a", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025.london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 2477648943.01459 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fa18df9ac5a270c92c38f235", + "semantic_fact_key": "ledger_semantic_fact_v2_cc9db3f47090569364b7f5be", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023.england.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 5513769841.09544 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5e83f4c1d95c23581ce13dab", + "semantic_fact_key": "ledger_semantic_fact_v2_f8c95b37ee0ded23cdf5d877", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024.england.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 6099523696.315949 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a3f98a1c4418e17b89e61a7e", + "semantic_fact_key": "ledger_semantic_fact_v2_02ce3e67089acb7e6ff6087e", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025.england.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 6616074977.27538 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5cdea26c4b486148afbd0700", + "semantic_fact_key": "ledger_semantic_fact_v2_1f89cf706a4872352ab9af78", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023.england_outside_london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2022-04-01", + "end_date": "2023-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2023", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 3363664711.83671 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_119c16fefe9279d51ba3d80a", + "semantic_fact_key": "ledger_semantic_fact_v2_0973f16836b63d76f24f0ea6", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024.england_outside_london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2023-04-01", + "end_date": "2024-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2024", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 3803029135.2795296 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_44db898d055be1615a643d79", + "semantic_fact_key": "ledger_semantic_fact_v2_b51e7eee6c7c45f29fe857fe", + "source_record_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025.england_outside_london.total_estimated_operating_revenue", + "concept": "dft.local_bus_total_estimated_operating_revenue", + "measure_id": "total_estimated_operating_revenue", + "unit": "gbp", + "aggregation": "sum", + "entity": { + "name": "institutional_sector", + "role": "local_bus_service_operators" + }, + "geography": { + "id": "dft:england_outside_london", + "level": "statistical_scope", + "vintage": "current" + }, + "period": { + "type": "fiscal_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2024-04-01", + "end_date": "2025-03-31", + "basis": "fiscal" + }, + "layout": { + "record_set_id": "dft.bus05i.bus05ai.gross_operating_revenue.fy2025", + "groupby_dimension": "dft.bus_area", + "groupby_value_id": "england_outside_london", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "BUS05i estimated operating revenue and net support for local bus services", + "source_file": "bus05i.ods", + "source_sha256": "a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5", + "vintage": "bus_statistics_2025", + "raw_r2_key": "raw/dft/dft-bus05i-revenue-support-2025/2025/a65ad97d70982bc572a8ff7415182c1b350166fc2e485e37f5678f3dbaa12fa5/bus05i.ods" + }, + "value": 4138426034.2607903 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_57e01f36a649a98dbf5e3ba2", + "semantic_fact_key": "ledger_semantic_fact_v2_489e68ce5b963c52f83910dc", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000001.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000001", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 2711380 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1d762192dc049cb6bd6087c1", + "semantic_fact_key": "ledger_semantic_fact_v2_fbcc150c0b790fbcb9c44d83", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000001.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000001", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000001", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 2760678 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_89ff962fee8a1f4c6f1ae36e", + "semantic_fact_key": "ledger_semantic_fact_v2_bef17399f98fd75e95ea8a65", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000002.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000002", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 7600126 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_095c7253be1254fdba821624", + "semantic_fact_key": "ledger_semantic_fact_v2_d387eaa29c0cbb012bc3bc17", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000002.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000002", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000002", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 7737414 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_2ff4b395bf1c6fa46ce9283f", + "semantic_fact_key": "ledger_semantic_fact_v2_5f460422d167445ee813a843", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000003.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000003", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 5594125 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ab1dee37dc3e0b2e92c50b97", + "semantic_fact_key": "ledger_semantic_fact_v2_30d470097e0f4c484c20a524", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000003.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000003", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000003", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 5672962 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cd8c691c08eeb7c7a4fefd04", + "semantic_fact_key": "ledger_semantic_fact_v2_6d84fa373d334102033dfb37", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000004.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000004", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 4991265 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8299a14d69e82d3dd55064cf", + "semantic_fact_key": "ledger_semantic_fact_v2_755c2cf28db00e017e53ea7d", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000004.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000004", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000004", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 5063164 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_344114125bdd3d6cfd2547d4", + "semantic_fact_key": "ledger_semantic_fact_v2_27bb104411c856b92ee0e8dd", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000005.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000005", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 6085687 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b844db8bfca8cd326b9a4fd7", + "semantic_fact_key": "ledger_semantic_fact_v2_0630975fd4309df6213f77dd", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000005.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000005", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000005", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 6187204 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fba28fb23256f90f52e3f576", + "semantic_fact_key": "ledger_semantic_fact_v2_4eed2bc02d51b5243840ccdd", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000006.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000006", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 6468665 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_334437ce3acd302adeabc030", + "semantic_fact_key": "ledger_semantic_fact_v2_7a4afa46c97bac3155c0993f", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000006.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000006", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000006", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 6576306 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_29652bfd574557ea4d684fc7", + "semantic_fact_key": "ledger_semantic_fact_v2_6b2a21ff568a0246cbfed6c3", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000007.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000007", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 8945309 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_29e13d09f68ec38286375728", + "semantic_fact_key": "ledger_semantic_fact_v2_8c7aaa39aca77a4a837f7d17", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000007.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000007", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000007", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 9089736 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0eefefdd40e6d2d0b74985b7", + "semantic_fact_key": "ledger_semantic_fact_v2_07bf692f271bb7037e6b529e", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000008.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000008", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 9482507 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7571796c43c1c5a11ab60246", + "semantic_fact_key": "ledger_semantic_fact_v2_47d0653630fc24f5466a852a", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000008.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000008", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000008", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 9642942 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_274e2d963b4fc1e836818462", + "semantic_fact_key": "ledger_semantic_fact_v2_fbae4e12b8152cd5bee7b4f6", + "source_record_id": "ons.mid2023.mye2_persons.england_regions.all_ages.e12000009.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.england_regions.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000009", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, England and Wales, by single year of age and sex (MYE2), 2023 local authority boundaries", + "source_file": "mye23tablesew.xlsx", + "source_sha256": "96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-england-regions/2023/96dcbb73d01c2965a0e8173bdf736f04a16d91dc189c4a52220919792e5e2c94/mye23tablesew.xlsx" + }, + "value": 5811259 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_72ab79d5b907418bbbf8a663", + "semantic_fact_key": "ledger_semantic_fact_v2_a12c6ce483529419f22e9afc", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.e12000009.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E12000009", + "level": "region", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "e12000009", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 5889695 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ed134450bebb0e771ad09459", + "semantic_fact_key": "ledger_semantic_fact_v2_ea26a31f63f4803bfc8ed989", + "source_record_id": "ons.mid2023.mye2_persons.uk_countries.all_ages.uk.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "K02000001", + "level": "country", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.uk_countries.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "uk", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, UK and constituent countries, by single year of age and sex (MYE2)", + "source_file": "mye23tablesuk.xlsx", + "source_sha256": "7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-uk-countries/2023/7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16/mye23tablesuk.xlsx" + }, + "value": 68265209 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6c212695ea75be0d2a635e9b", + "semantic_fact_key": "ledger_semantic_fact_v2_065ea5242b0c7b9f810a9ce6", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.uk.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "K02000001", + "level": "country", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "uk", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 69281437 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3d14b0d3d5d58c4697ed9ba4", + "semantic_fact_key": "ledger_semantic_fact_v2_b74539d56136e68b0461a1dd", + "source_record_id": "ons.mid2023.mye2_persons.uk_countries.all_ages.northern_ireland.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.uk_countries.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "northern_ireland", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, UK and constituent countries, by single year of age and sex (MYE2)", + "source_file": "mye23tablesuk.xlsx", + "source_sha256": "7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-uk-countries/2023/7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16/mye23tablesuk.xlsx" + }, + "value": 1920382 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_442e03a093f4b4bc65f0bc69", + "semantic_fact_key": "ledger_semantic_fact_v2_04fc034cd63b902edc8d449e", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.northern_ireland.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "N92000002", + "level": "country", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "northern_ireland", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 1927855 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7e7a46b0c75391ea8a402512", + "semantic_fact_key": "ledger_semantic_fact_v2_2ae20a26cdcd39098d13c08f", + "source_record_id": "ons.mid2023.mye2_persons.uk_countries.all_ages.scotland.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "S92000003", + "level": "country", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.uk_countries.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "scotland", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, UK and constituent countries, by single year of age and sex (MYE2)", + "source_file": "mye23tablesuk.xlsx", + "source_sha256": "7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-uk-countries/2023/7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16/mye23tablesuk.xlsx" + }, + "value": 5490100 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_63860b3eaa56261e3abbc9ce", + "semantic_fact_key": "ledger_semantic_fact_v2_5620ba8e80c76eb75fdff1e5", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.scotland.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "S92000003", + "level": "country", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "scotland", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 5546900 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0d08a2a88f61f28cab9c46e4", + "semantic_fact_key": "ledger_semantic_fact_v2_2100b926763ce55afbf068f4", + "source_record_id": "ons.mid2023.mye2_persons.uk_countries.all_ages.wales.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "W92000004", + "level": "country", + "vintage": "gss_2023" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2023.mye2_persons.uk_countries.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "wales", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2023 population estimates, UK and constituent countries, by single year of age and sex (MYE2)", + "source_file": "mye23tablesuk.xlsx", + "source_sha256": "7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16", + "vintage": "mid_2023", + "raw_r2_key": "raw/ons/ons-mye-2023-uk-countries/2023/7ee5724ecf71abc3d811c89174cdddf1bce7f07d3eefc8b69b15ee8371414b16/mye23tablesuk.xlsx" + }, + "value": 3164404 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_257be15629bb42a47657dcab", + "semantic_fact_key": "ledger_semantic_fact_v2_ff973486410cb2b5df9a175a", + "source_record_id": "ons.mid2024.mye2_persons.uk.all_ages.wales.population", + "concept": "ons.mid_year_population_estimate", + "measure_id": "population", + "unit": "count", + "aggregation": "sum", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "W92000004", + "level": "country", + "vintage": "gss_2024" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "ons.mid2024.mye2_persons.uk.all_ages", + "groupby_dimension": "age", + "groupby_value_id": "wales", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "ons", + "source_table": "Mid-2024 population estimates, UK: countries and regions by single year of age and sex (MYE2)", + "source_file": "mye24tablesuk.xlsx", + "source_sha256": "f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526", + "vintage": "mid_2024", + "raw_r2_key": "raw/ons/ons-mye-2024-uk/2024/f78d50e8d77fe5ed9d04667d6875aefcf62b56380af7aceb2e90dce067981526/mye24tablesuk.xlsx" + }, + "value": 3186581 + } + ] +} diff --git a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_value_anchors.json b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_value_anchors.json index e409c5f31..008812782 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_value_anchors.json +++ b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_value_anchors.json @@ -17,12 +17,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { @@ -75,7 +75,8 @@ "dft.other_local_bus_trips_per_person", "dft.bus_in_london_trips_per_person" ], - "period_type": "calendar_year" + "period_type": "calendar_year", + "groupby_dimension": "dft.household_income_quintile" }, "row_count": 24 } diff --git a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json index 4d8b3895c..7fd1519f2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json @@ -64,7 +64,8 @@ "dft.other_local_bus_trips_per_person", "dft.bus_in_london_trips_per_person" ], - "period_type": "calendar_year" + "period_type": "calendar_year", + "groupby_dimension": "dft.household_income_quintile" }, "expected_row_count": 24 } @@ -280,7 +281,7 @@ }, { "resource": "devolved_bus_finance.json", - "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets.", + "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets; DfI Northern Ireland Translink full-fare concession passenger journeys by fiscal year (the concessionary split for the Northern Ireland bus price).", "consumers": [ "uk_runtime.lcfs_consumption", "uk_runtime.etb_services" @@ -335,6 +336,15 @@ "period_type": "fiscal_year" }, "expected_row_count": 24 + }, + { + "label": "dfi_ni_translink_bus_full_fare_concession_journeys", + "selector": { + "source_name": "dfi_ni", + "source_concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "period_type": "fiscal_year" + }, + "expected_row_count": 6 } ] }, @@ -570,6 +580,208 @@ "expected_row_count": 12 } ] + }, + { + "resource": "dft_bus_journeys.json", + "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.lcfs_consumption", + "uk_runtime.etb_services", + "uk_runtime.bus_fare_pricing" + ], + "selections": [ + { + "label": "bus01a_passenger_journeys_by_area", + "selector": { + "source_name": "dft", + "source_concept": "dft.local_bus_passenger_journeys", + "period_type": "fiscal_year", + "period_value": [ + "2023", + "2024", + "2025" + ], + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london", + "dft:english_metropolitan_areas", + "dft:english_non_metropolitan_areas", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimensions": [] + }, + "expected_row_count": 39 + }, + { + "label": "bus01c_concessionary_journeys_by_area", + "selector": { + "source_name": "dft", + "source_concept": "dft.local_bus_passenger_journeys", + "period_type": "fiscal_year", + "period_value": [ + "2023", + "2024", + "2025" + ], + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london", + "dft:english_metropolitan_areas", + "dft:english_non_metropolitan_areas", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimension_values": { + "journey_category": [ + "elderly_disabled_concessionary", + "total_concessionary" + ] + } + }, + "expected_row_count": 78 + }, + { + "label": "bus05i_revenue_and_support_components", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.local_bus_concessionary_travel_reimbursement", + "dft.local_bus_bus_service_operators_grant", + "dft.local_bus_gross_public_transport_support", + "dft.local_bus_net_public_transport_support", + "dft.local_bus_total_estimated_operating_revenue", + "dft.local_bus_additional_funding_to_operators", + "dft.local_bus_fare_cap" + ], + "period_type": "fiscal_year", + "geography_id": [ + "E92000001", + "E12000007", + "dft:england_outside_london" + ] + }, + "expected_row_count": 54 + }, + { + "label": "ons_mid_year_population_countries_and_english_regions", + "selector": { + "source_name": "ons", + "source_concept": "ons.mid_year_population_estimate", + "period_type": "calendar_year", + "geography_id": [ + "K02000001", + "S92000003", + "W92000004", + "N92000002", + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "dimensions": [] + }, + "expected_row_count": 26 + } + ] + }, + { + "resource": "nts_trip_rates.json", + "purpose": "DfT NTS0303 average trips per person per year by main mode (all modes, bus in London, other local bus; England, all ages) and NTS0601 the same rates by age band, survey years 2023 to 2025. Consumed by the NTS bus-travel stage's fact checks on the imputed trip rates by age and the level of local-bus trips per resident (microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.nts_bus_travel" + ], + "selections": [ + { + "label": "nts0303_trips_per_person_by_mode", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.all_modes_trips_per_person", + "dft.bus_in_london_trips_per_person", + "dft.other_local_bus_trips_per_person" + ], + "groupby_dimension": "dft.survey_year", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024", + "2025" + ] + }, + "expected_row_count": 9 + }, + { + "label": "nts0601_trips_per_person_by_age_band", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.all_modes_trips_per_person", + "dft.bus_in_london_trips_per_person", + "dft.other_local_bus_trips_per_person" + ], + "groupby_dimension": "dft.age_band", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024", + "2025" + ] + }, + "expected_row_count": 81 + } + ] + }, + { + "resource": "nts_car_availability.json", + "purpose": "DfT NTS0205 shares of households with no car or van, one, and two or more (England, survey years 2023 and 2024). Consumed by the NTS bus-travel stage's receipt of the frame's num_vehicles distribution against the published shares (microcosm#890 item A, carried by microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.nts_bus_travel" + ], + "selections": [ + { + "label": "nts0205_household_car_availability_england", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.households_no_car_share", + "dft.households_one_car_share", + "dft.households_two_plus_cars_share" + ], + "geography_id": "E92000001", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024" + ] + }, + "expected_row_count": 6 + } + ] } ] } diff --git a/packages/microcosm-build/src/microcosm/build/uk/licensed_cars_fuel_type.json b/packages/microcosm-build/src/microcosm/build/uk/licensed_cars_fuel_type.json index 5f80e8ec3..0c7e2619c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/licensed_cars_fuel_type.json +++ b/packages/microcosm-build/src/microcosm/build/uk/licensed_cars_fuel_type.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/local_target_reference_membership.json b/packages/microcosm-build/src/microcosm/build/uk/local_target_reference_membership.json index 98563ed70..2c392e652 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/local_target_reference_membership.json +++ b/packages/microcosm-build/src/microcosm/build/uk/local_target_reference_membership.json @@ -1,5 +1,5 @@ { - "source_fact_feed": "chronicle-uk-c5e5bf8a-consumer-facts", + "source_fact_feed": "chronicle-uk-78466057-consumer-facts", "target_period": 2025, "candidate_count": 22464, "contract_target_count": 51, diff --git a/packages/microcosm-build/src/microcosm/build/uk/local_validation_levels.json b/packages/microcosm-build/src/microcosm/build/uk/local_validation_levels.json index 39c2645c7..8c69b722b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/local_validation_levels.json +++ b/packages/microcosm-build/src/microcosm/build/uk/local_validation_levels.json @@ -5,10 +5,10 @@ "source_feed": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", + "sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f" + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba" }, "rows": [ { @@ -19,10 +19,7 @@ "in_sample": false, "geography_id": "S92000003", "period": 2025, - "estimate": { - "metric_name": "rent/private_rent", - "reduction": "sum" - }, + "estimate": {"metric_name": "rent/private_rent", "reduction": "sum"}, "available_component_selector": { "record_set_id": "ons.pipr.june2026.average_rent_by_area", "source_measure_id": "private_rent", @@ -39,10 +36,7 @@ "in_sample": false, "geography_id": "W92000004", "period": 2025, - "estimate": { - "metric_name": "rent/private_rent", - "reduction": "sum" - }, + "estimate": {"metric_name": "rent/private_rent", "reduction": "sum"}, "available_component_selector": { "record_set_id": "ons.pipr.june2026.average_rent_by_area", "source_measure_id": "private_rent", @@ -59,10 +53,7 @@ "in_sample": true, "geography_id": "W92000004", "period": 2025, - "estimate": { - "target_id": "dwp.uc.households_by_area", - "reduction": "sum" - }, + "estimate": {"target_id": "dwp.uc.households_by_area", "reduction": "sum"}, "needs_facts": "The pinned feed has constituency UC households but no Wales-country UC household benchmark row.", "evidence": "uk-data#206 and uk-data#316 Welsh constituency-sum credibility check." }, @@ -74,16 +65,10 @@ "in_sample": true, "geography_id": "W92000004", "period": 2025, - "estimate": { - "target_id": "hmrc.employment_income.amount", - "reduction": "sum" - }, + "estimate": {"target_id": "hmrc.employment_income.amount", "reduction": "sum"}, "benchmark_selector": { "record_set_id": "hmrc.ty2023_24.spi.by_parliamentary_constituency", - "source_measure_ids": [ - "employment_income_count", - "employment_income_mean" - ], + "source_measure_ids": ["employment_income_count", "employment_income_mean"], "geography_id": "W92000004", "fact_period": 2023, "reduction": "count_x_mean" @@ -98,16 +83,10 @@ "in_sample": true, "geography_id": "W92000004", "period": 2025, - "estimate": { - "target_id": "hmrc.self_employment_income.amount", - "reduction": "sum" - }, + "estimate": {"target_id": "hmrc.self_employment_income.amount", "reduction": "sum"}, "benchmark_selector": { "record_set_id": "hmrc.ty2023_24.spi.by_parliamentary_constituency", - "source_measure_ids": [ - "self_employment_income_count", - "self_employment_income_mean" - ], + "source_measure_ids": ["self_employment_income_count", "self_employment_income_mean"], "geography_id": "W92000004", "fact_period": 2023, "reduction": "count_x_mean" @@ -122,10 +101,7 @@ "in_sample": false, "geography_id": "E92000001", "period": 2025, - "estimate": { - "metric_name": "council_tax/net", - "reduction": "sum" - }, + "estimate": {"metric_name": "council_tax/net", "reduction": "sum"}, "benchmark_selector": { "record_set_id": "mhclg.ct_collection_2025_26.table_5.net_collectable_debit.fy2025", "source_measure_id": "amount", @@ -142,10 +118,7 @@ "in_sample": false, "geography_id": "W92000004", "period": 2025, - "estimate": { - "metric_name": "council_tax/net", - "reduction": "sum" - }, + "estimate": {"metric_name": "council_tax/net", "reduction": "sum"}, "benchmark_selector": { "record_set_id": "welshgov.ct_collection_2025_26.table_2.wales", "source_measure_id": "net_collectable_debit", @@ -162,10 +135,7 @@ "in_sample": false, "geography_id": "S92000003", "period": 2025, - "estimate": { - "metric_name": "council_tax/net", - "reduction": "sum" - }, + "estimate": {"metric_name": "council_tax/net", "reduction": "sum"}, "benchmark_selector": { "record_set_id": "scotgov.slgfs_2024_25.table_2_8.council_tax_income_after_ctr.scotland", "source_measure_id": "council_tax_income_after_ctr", @@ -182,10 +152,7 @@ "in_sample": false, "geography_id": "all_uk_regions", "period": 2025, - "estimate": { - "target_id": "ons.public_sector_employment", - "reduction": "sum_by_region" - }, + "estimate": {"target_id": "ons.public_sector_employment", "reduction": "sum_by_region"}, "needs_facts": "The pinned feed carries the national ONS PSE control but no regional PSE record set; a Chronicle fact package is required.", "evidence": "uk-data national PSE credibility test; microcosm#147 I7 regional placeholder ruling." } diff --git a/packages/microcosm-build/src/microcosm/build/uk/need_energy_facts.json b/packages/microcosm-build/src/microcosm/build/uk/need_energy_facts.json index 32c5f08cf..4e90b66de 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/need_energy_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/need_energy_facts.json @@ -17,12 +17,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json index d20f33412..6612d3f57 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json @@ -16,12 +16,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json b/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json new file mode 100644 index 000000000..3c35d9722 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json @@ -0,0 +1,306 @@ +{ + "schema_version": 1, + "country": "uk", + "kind": "uk_vendored_ledger_facts", + "resource": "nts_car_availability.json", + "purpose": "DfT NTS0205 shares of households with no car or van, one, and two or more (England, survey years 2023 and 2024). Consumed by the NTS bus-travel stage's receipt of the frame's num_vehicles distribution against the published shares (microcosm#890 item A, carried by microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.nts_bus_travel" + ], + "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", + "generator": { + "tool": "tools/vendor_uk_ledger_facts.py", + "version": 1 + }, + "source_fact_feed": { + "source_repo": "PolicyEngine/chronicle", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", + "build": "build-bundle --suite uk -> build-consumer-artifact", + "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" + }, + "selections": [ + { + "label": "nts0205_household_car_availability_england", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.households_no_car_share", + "dft.households_one_car_share", + "dft.households_two_plus_cars_share" + ], + "geography_id": "E92000001", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024" + ] + }, + "row_count": 6 + } + ], + "row_count": 6, + "rows": [ + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0237373e16baae05b366a2ed", + "semantic_fact_key": "ledger_semantic_fact_v2_85161169b325f9bc59977495", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2023.cy2023.no_car", + "concept": "dft.households_no_car_share", + "measure_id": "no_car", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2023", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 22.4483535780402 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_408e7a6e98f95110082a847a", + "semantic_fact_key": "ledger_semantic_fact_v2_d642166f2cb2c112d4b4567a", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2024.cy2024.no_car", + "concept": "dft.households_no_car_share", + "measure_id": "no_car", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2024", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 21.784588632006 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c6785d856a4f536c72b7b2e0", + "semantic_fact_key": "ledger_semantic_fact_v2_6619b7566cedcadc43203ff4", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2023.cy2023.one_car", + "concept": "dft.households_one_car_share", + "measure_id": "one_car", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2023", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 44.0060556986154 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4295590e0a69b11c8f49d3f5", + "semantic_fact_key": "ledger_semantic_fact_v2_f4bcb025f216b745b4693a29", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2024.cy2024.one_car", + "concept": "dft.households_one_car_share", + "measure_id": "one_car", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2024", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 44.2490898162473 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a8434798a4f88de24ecff2d1", + "semantic_fact_key": "ledger_semantic_fact_v2_d936a616d098f02b3f5884e2", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2023.cy2023.two_plus_cars", + "concept": "dft.households_two_plus_cars_share", + "measure_id": "two_plus_cars", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2023", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 33.5455907233445 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b13697e505f28ea011eca173", + "semantic_fact_key": "ledger_semantic_fact_v2_9a80bbf7bb34db7fbbf36fc9", + "source_record_id": "dft.nts2024.nts0205a.car_availability.cy2024.cy2024.two_plus_cars", + "concept": "dft.households_two_plus_cars_share", + "measure_id": "two_plus_cars", + "unit": "percent", + "aggregation": "share", + "entity": { + "name": "household", + "role": "resident_household" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": null, + "end_date": null, + "basis": null + }, + "layout": { + "record_set_id": "dft.nts2024.nts0205a.car_availability.cy2024", + "groupby_dimension": "dft.car_availability_band", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "National Travel Survey 2024, table NTS0205 household car availability", + "source_file": "nts-2024-excel-tables.zip!nts0205.xlsx", + "source_sha256": "8bcc103e8f2398741ae2dce8e200d4fbbbf0e39afa0cc32d303434def69992e5", + "vintage": "nts_2024", + "raw_r2_key": "raw/dft/dft-nts-vehicle-ownership-2024/2024/f36b277c3bbb243858d171a8dcd3ad086d76d8afdb53d63b9884df6597071938/nts-2024-excel-tables.zip" + }, + "value": 33.9663215517466 + } + ] +} diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json b/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json new file mode 100644 index 000000000..23bef790e --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json @@ -0,0 +1,4181 @@ +{ + "schema_version": 1, + "country": "uk", + "kind": "uk_vendored_ledger_facts", + "resource": "nts_trip_rates.json", + "purpose": "DfT NTS0303 average trips per person per year by main mode (all modes, bus in London, other local bus; England, all ages) and NTS0601 the same rates by age band, survey years 2023 to 2025. Consumed by the NTS bus-travel stage's fact checks on the imputed trip rates by age and the level of local-bus trips per resident (microcosm#930).", + "consumers": [], + "planned_consumers": [ + "uk_runtime.nts_bus_travel" + ], + "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", + "generator": { + "tool": "tools/vendor_uk_ledger_facts.py", + "version": 1 + }, + "source_fact_feed": { + "source_repo": "PolicyEngine/chronicle", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", + "build": "build-bundle --suite uk -> build-consumer-artifact", + "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" + }, + "selections": [ + { + "label": "nts0303_trips_per_person_by_mode", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.all_modes_trips_per_person", + "dft.bus_in_london_trips_per_person", + "dft.other_local_bus_trips_per_person" + ], + "groupby_dimension": "dft.survey_year", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024", + "2025" + ] + }, + "row_count": 9 + }, + { + "label": "nts0601_trips_per_person_by_age_band", + "selector": { + "source_name": "dft", + "source_concept": [ + "dft.all_modes_trips_per_person", + "dft.bus_in_london_trips_per_person", + "dft.other_local_bus_trips_per_person" + ], + "groupby_dimension": "dft.age_band", + "period_type": "calendar_year", + "period_value": [ + "2023", + "2024", + "2025" + ] + }, + "row_count": 81 + } + ], + "row_count": 90, + "rows": [ + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6cd8cb8c5acd36cf5b95087d", + "semantic_fact_key": "ledger_semantic_fact_v2_79ba832bc151ba5803635365", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_0_to_16.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 788.870214845467 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_97dc2150b09f7ba7758d5080", + "semantic_fact_key": "ledger_semantic_fact_v2_69b4aa69c1a2ce12107a6794", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_17_to_20.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 709.843179051385 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_de475225c1220a1201622a7f", + "semantic_fact_key": "ledger_semantic_fact_v2_dbd8719bf0b807b2c95f16ec", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_21_to_29.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 842.400765037472 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e5687a99bbd997637d6ec491", + "semantic_fact_key": "ledger_semantic_fact_v2_8d044419662626f49c6a87ac", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_30_to_39.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 996.03763051672 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_60d48497c669112d88b168f1", + "semantic_fact_key": "ledger_semantic_fact_v2_e76d0bdb8503708c1a12ee16", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_40_to_49.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 1097.34904595885 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_60720166f502f5e6a1624288", + "semantic_fact_key": "ledger_semantic_fact_v2_06f0c5073bf2cabf99ed18ff", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_50_to_59.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 1032.12439252329 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ae6796b5fe5891d061427b30", + "semantic_fact_key": "ledger_semantic_fact_v2_e08e6abb8a7c96afc376af35", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_60_to_69.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 966.574301408932 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_785402e0a3aa37f703957616", + "semantic_fact_key": "ledger_semantic_fact_v2_c3419e668bca2df55ec98c22", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_70_and_over.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 810.695472873024 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c9dbd8e7abaccd39593ddc57", + "semantic_fact_key": "ledger_semantic_fact_v2_d6bcf5ed523bb076bd7a92b5", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.all_ages.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 915.293045573491 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_9e1fe1fbb13da8be7e2f447d", + "semantic_fact_key": "ledger_semantic_fact_v2_2b85a1caf9768aa9a57edbce", + "source_record_id": "dft.nts0303a.mode_trips.cy2023.cy2023.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2023", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 915.293045573491 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_6584548405000655d794c037", + "semantic_fact_key": "ledger_semantic_fact_v2_26c3c082ed402719d3b08472", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_0_to_16.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 804.099137624011 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_98a801bd6db785b5f67e164d", + "semantic_fact_key": "ledger_semantic_fact_v2_3c7684d3583303358431eb0d", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_17_to_20.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 736.009328480068 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_dfe785d1d15397bd2cbbed7b", + "semantic_fact_key": "ledger_semantic_fact_v2_327f05d25c4bb9c1c6f9bd30", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_21_to_29.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 850.676436788137 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7b09e4b1e5ffab44227e9bd8", + "semantic_fact_key": "ledger_semantic_fact_v2_8640006b7cb6ca4991714da3", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_30_to_39.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 1023.08633877304 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_45501eb1c197f5758e248a33", + "semantic_fact_key": "ledger_semantic_fact_v2_ed1f4fea07edba3c03bab9cc", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_40_to_49.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 1047.4480089754 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ae79630f655dd05c6ad36eb1", + "semantic_fact_key": "ledger_semantic_fact_v2_b51459b7c8ef5cf057669eda", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_50_to_59.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 1027.90363535261 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c7de5da3445d42bd732245fa", + "semantic_fact_key": "ledger_semantic_fact_v2_ae10cbd3d588e9ce6c5a53c5", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_60_to_69.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 999.931259688495 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f6a42e551528b5117acf07e4", + "semantic_fact_key": "ledger_semantic_fact_v2_d1755930ab1fed2365ab3ac8", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_70_and_over.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 818.309699678068 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_88e78ff622ebdec3abb885a9", + "semantic_fact_key": "ledger_semantic_fact_v2_5dbb267a5f6cd91884288770", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.all_ages.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 921.806459412313 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4a71786fa92f8d5fb2b5eb70", + "semantic_fact_key": "ledger_semantic_fact_v2_8711cdfed4ad45697f747234", + "source_record_id": "dft.nts0303a.mode_trips.cy2024.cy2024.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2024", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 921.806459412313 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7573be26e41003af6531f2f6", + "semantic_fact_key": "ledger_semantic_fact_v2_b8a513bc1754dcdfee300ea0", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_0_to_16.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 744.36368714882 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1ac0e79e254054249c5694d5", + "semantic_fact_key": "ledger_semantic_fact_v2_ec93851e6fc458466b264982", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_17_to_20.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 620.375479324839 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f7e8027a8cabc28c738464ca", + "semantic_fact_key": "ledger_semantic_fact_v2_bea0f82d9b51bada87ad1d6b", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_21_to_29.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 706.541136829928 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_89341dbf37ec79357fa9aaf8", + "semantic_fact_key": "ledger_semantic_fact_v2_9442e9e84c03ada3360c7d7e", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_30_to_39.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 930.170603547636 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_932e3fa07a72ce0cf51a3b76", + "semantic_fact_key": "ledger_semantic_fact_v2_c7280098c719c30445d35592", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_40_to_49.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 984.072419714394 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_83974721b744e9d59ae4de2b", + "semantic_fact_key": "ledger_semantic_fact_v2_c8bedb0adfe66d081c19798c", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_50_to_59.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 926.658538330061 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fe6e37cf8298db86836c6f09", + "semantic_fact_key": "ledger_semantic_fact_v2_44f9992aeffceea46d201947", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_60_to_69.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 923.154292874512 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_714571743dd548fdafdb7e39", + "semantic_fact_key": "ledger_semantic_fact_v2_b158da054b394a535ec58a86", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_70_and_over.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 783.246318341494 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_f88154f5fd403065015c17d8", + "semantic_fact_key": "ledger_semantic_fact_v2_ff553dafcd036beab0f316b4", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.all_ages.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 840.582374315825 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8a155e55eccd640d3577debd", + "semantic_fact_key": "ledger_semantic_fact_v2_9090f9336d2f89f90cb4d218", + "source_record_id": "dft.nts0303a.mode_trips.cy2025.cy2025.all_modes_trips_per_person", + "concept": "dft.all_modes_trips_per_person", + "measure_id": "all_modes_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2025", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2025", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 840.582374315825 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_043805a61b80293f683e6c65", + "semantic_fact_key": "ledger_semantic_fact_v2_42547b97b4ff9f3323488761", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_0_to_16.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.351129510862 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0afe0e28218c6ee541a78e5f", + "semantic_fact_key": "ledger_semantic_fact_v2_f65caa6d67cd274c4875fff3", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_17_to_20.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 27.2827713964697 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_07d2021d8645d18e44ca4be5", + "semantic_fact_key": "ledger_semantic_fact_v2_c5fb35808eaf41bcfe47076d", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_21_to_29.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 20.6266409538376 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0e12125333a73e0c2d8e6bb7", + "semantic_fact_key": "ledger_semantic_fact_v2_64a45d0ebd79db6e4c7a088a", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_30_to_39.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 15.8129619689879 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e505278b9d19c717cce00bfc", + "semantic_fact_key": "ledger_semantic_fact_v2_2af500189b7c9d28a5a64270", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_40_to_49.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 13.6081338608428 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d78204043b5742a0a3374513", + "semantic_fact_key": "ledger_semantic_fact_v2_24af10451602d31ec48bf984", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_50_to_59.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 9.53283074646507 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_58fb02fbdcb7f5cda638030c", + "semantic_fact_key": "ledger_semantic_fact_v2_7d6b30ee42a9fe6dff89c762", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_60_to_69.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 13.7555338391058 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_137c75f6a3b783e362b67df2", + "semantic_fact_key": "ledger_semantic_fact_v2_8cb4f77259d1d07e5f5c11a2", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_70_and_over.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 10.5575855600522 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_76befc56f9608f5ff806909e", + "semantic_fact_key": "ledger_semantic_fact_v2_ca8668d5e263a594ec813d3f", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.all_ages.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.0687444929693 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d29aaa9128d0121008a025c3", + "semantic_fact_key": "ledger_semantic_fact_v2_9598aa3edb90ca01d5fccab1", + "source_record_id": "dft.nts0303a.mode_trips.cy2023.cy2023.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2023", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 14.0687444929693 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_61a48e9a1aee4776bbb430f1", + "semantic_fact_key": "ledger_semantic_fact_v2_52070a1a1773774a19babc92", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_0_to_16.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.1770296913304 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a505313293a0fd4ec6e923fd", + "semantic_fact_key": "ledger_semantic_fact_v2_18ef89691d54aa06c2386a47", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_17_to_20.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 22.2509807468839 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_04a263d25b9064b876aa322f", + "semantic_fact_key": "ledger_semantic_fact_v2_3613367e856eb5afdbd14c77", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_21_to_29.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.4256764762614 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_00894a216c51e17580570946", + "semantic_fact_key": "ledger_semantic_fact_v2_7b082d3da06e90eb3afabaeb", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_30_to_39.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.5026184092548 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_973586b16b73445df2a72aed", + "semantic_fact_key": "ledger_semantic_fact_v2_cd43bfc576e4e1dec59d6464", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_40_to_49.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.2850781887529 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7ede3bf424d4daad0b43bc40", + "semantic_fact_key": "ledger_semantic_fact_v2_ca639cc8c0a08403e1de1a73", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_50_to_59.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 10.4120219834301 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4a74e8a6470b1cc54bf1eb2b", + "semantic_fact_key": "ledger_semantic_fact_v2_dbf6ee6ed508e6c66aef1de7", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_60_to_69.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.3972711622741 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4d26b51a6137b2b7b218d86d", + "semantic_fact_key": "ledger_semantic_fact_v2_c80ecd9f89c0ace8fd209b92", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_70_and_over.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.1540228639839 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7c1a5369d07e64128bb6e1b0", + "semantic_fact_key": "ledger_semantic_fact_v2_605b5e682a996bdf45d36265", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.all_ages.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 13.1155774642333 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_9d489026dcd764df744a2958", + "semantic_fact_key": "ledger_semantic_fact_v2_7f937f775f3aa7c7248e0235", + "source_record_id": "dft.nts0303a.mode_trips.cy2024.cy2024.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2024", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 13.1155774642333 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_af67d37d4149ece9d344bfaa", + "semantic_fact_key": "ledger_semantic_fact_v2_09589a4f739331e91847e79d", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_0_to_16.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 15.6213173419227 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_7528182f9c72c37ca5c90c04", + "semantic_fact_key": "ledger_semantic_fact_v2_662f3dbf7c26ce98e1ab70bd", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_17_to_20.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 19.7700845867196 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_73339f04adb9af59cde510f2", + "semantic_fact_key": "ledger_semantic_fact_v2_5b3c65150a1d6a0d23f6009a", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_21_to_29.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 16.9845226111601 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5761f5ca236eacb730fc35b5", + "semantic_fact_key": "ledger_semantic_fact_v2_7f2275882145205e6af98770", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_30_to_39.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 13.701504088504 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d4b0bf926cbf20da3f7e2200", + "semantic_fact_key": "ledger_semantic_fact_v2_69f6e26d87a7e08cd4016b3c", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_40_to_49.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 15.0928260377259 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fe983aac36b66ff77bcea42c", + "semantic_fact_key": "ledger_semantic_fact_v2_89625423fdbb090329c8a179", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_50_to_59.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 13.1172786284122 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8b30fa9f41f99c523341f584", + "semantic_fact_key": "ledger_semantic_fact_v2_06c836de0bcea2b5261c8819", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_60_to_69.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 12.0857252971509 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0f4b798e7cce2b98f50a7e72", + "semantic_fact_key": "ledger_semantic_fact_v2_16aac5f512bd4b558ab041e9", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_70_and_over.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.2388772737541 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_15f37ac004a9450136bbaf7d", + "semantic_fact_key": "ledger_semantic_fact_v2_2912a6a4d553f8c86d44aa66", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.all_ages.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.703747432279 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_21d0e33cfce6ba701a555439", + "semantic_fact_key": "ledger_semantic_fact_v2_a8d701154a46b4c01d12226d", + "source_record_id": "dft.nts0303a.mode_trips.cy2025.cy2025.bus_in_london_trips_per_person", + "concept": "dft.bus_in_london_trips_per_person", + "measure_id": "bus_in_london_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2025", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2025", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 14.703747432279 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_834264b3ab6be47282f12e75", + "semantic_fact_key": "ledger_semantic_fact_v2_c13dccbac6e804af50c1da8d", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_0_to_16.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 26.7793478224147 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_95683bbaebb16204b7223cc8", + "semantic_fact_key": "ledger_semantic_fact_v2_dc041ef6186ee93c1469f158", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_17_to_20.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 57.0942758457833 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_71a510e900035e1ca9435d2c", + "semantic_fact_key": "ledger_semantic_fact_v2_8e970ee047e80f061c59509b", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_21_to_29.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 27.2838405317941 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fed89d0d7e346cbed466e615", + "semantic_fact_key": "ledger_semantic_fact_v2_d74241566201346db92120b0", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_30_to_39.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 24.2835281021163 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8b2c5f6c3d1f9a05b0131df5", + "semantic_fact_key": "ledger_semantic_fact_v2_f3b060cd0be0372a544fd588", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_40_to_49.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 16.4434784368462 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_5016f4147c665c0651bc10b8", + "semantic_fact_key": "ledger_semantic_fact_v2_f7c088be8172258607c3e51f", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_50_to_59.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 14.6383286695019 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_fa6a4208062a020eb7dabf11", + "semantic_fact_key": "ledger_semantic_fact_v2_d3fa943b8f86f47a9c9bc0bb", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_60_to_69.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 21.7814384195701 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b41613ff414d915c13f1aab5", + "semantic_fact_key": "ledger_semantic_fact_v2_507ba1c7224da4d6a8a5dcc7", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.age_70_and_over.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 33.0383448627926 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_09faa29f6001c432b3da8982", + "semantic_fact_key": "ledger_semantic_fact_v2_aa5ec266359a6906c14ee8ef", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2023.all_ages.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2023", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 25.0671459605513 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d42f34bd5a0b3d55756df448", + "semantic_fact_key": "ledger_semantic_fact_v2_bc72172f341a84aa234452f9", + "source_record_id": "dft.nts0303a.mode_trips.cy2023.cy2023.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2023 + }, + "period_coverage": { + "start_date": "2023-01-01", + "end_date": "2023-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2023", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2023", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 25.0671459605513 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_bf0413048d1d7f0f735e1185", + "semantic_fact_key": "ledger_semantic_fact_v2_791f8300cb5396a4a6a4a478", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_0_to_16.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 29.6801694294585 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_38bf40aa3161b3bf0ba02af1", + "semantic_fact_key": "ledger_semantic_fact_v2_28bd866d1e33c53e7d232ade", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_17_to_20.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 65.4899089582547 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_c2514f8ce7df175fc4d1c665", + "semantic_fact_key": "ledger_semantic_fact_v2_f1d1fac4ec0d10c37a4f72d3", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_21_to_29.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 35.9830691395679 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ab9c2173f470a5e706387db6", + "semantic_fact_key": "ledger_semantic_fact_v2_1cab345ad09a397b8e1e3308", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_30_to_39.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 25.3574370692756 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_44104356a307c4b0e4b9be7f", + "semantic_fact_key": "ledger_semantic_fact_v2_699430597e1ab3f10522c14e", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_40_to_49.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 19.4438163785248 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_ed0d1dcf7002ec243b15799d", + "semantic_fact_key": "ledger_semantic_fact_v2_bf9572b61d4802303f5bae78", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_50_to_59.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 17.1021792942901 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_a76f9873575aaa5faf1545a6", + "semantic_fact_key": "ledger_semantic_fact_v2_6ca0c9b8ec524da72fb601b5", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_60_to_69.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 21.8462623528516 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e3a6d3709dba6babfd9b3c5a", + "semantic_fact_key": "ledger_semantic_fact_v2_eb366f8128b63d667b71deed", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.age_70_and_over.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 34.8004103450646 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_e247cd8b566500557853954c", + "semantic_fact_key": "ledger_semantic_fact_v2_4fd3c38fbf8bb05d5d0e8b00", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2024.all_ages.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2024", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 28.0685543170643 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_0c2e0f86f2a11f056d2fde7a", + "semantic_fact_key": "ledger_semantic_fact_v2_0298115c7956775d9878017b", + "source_record_id": "dft.nts0303a.mode_trips.cy2024.cy2024.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2024 + }, + "period_coverage": { + "start_date": "2024-01-01", + "end_date": "2024-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2024", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2024", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 28.0685543170643 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_cea1eb53ab413cec73c3fd33", + "semantic_fact_key": "ledger_semantic_fact_v2_432f84e86ac25c5328b8bf5b", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_0_to_16.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_0_to_16", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "0 to 16", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 28.2559617350621 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_bc7ccdc881fc0dfbb50c1a7c", + "semantic_fact_key": "ledger_semantic_fact_v2_89f1f6a4b105e5672c69e76c", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_17_to_20.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_17_to_20", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "17 to 20", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 63.0524537460203 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_51247f7270ea7990596853d6", + "semantic_fact_key": "ledger_semantic_fact_v2_ce551d8944952cdb00ceabcc", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_21_to_29.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_21_to_29", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "21 to 29", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 33.7064010416618 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_8e02a45a076c7fb3dcef0b05", + "semantic_fact_key": "ledger_semantic_fact_v2_7ff248c8410629d073d27a51", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_30_to_39.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_30_to_39", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "30 to 39", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 22.7385012451484 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_1c58da6151973727533aa91e", + "semantic_fact_key": "ledger_semantic_fact_v2_e70b1a0ddda01ffe8e478865", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_40_to_49.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_40_to_49", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "40 to 49", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 18.3290590121647 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_d6084a3b39d53da7be88de2e", + "semantic_fact_key": "ledger_semantic_fact_v2_d12ec0758dc4abbff7527c44", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_50_to_59.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_50_to_59", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "50 to 59", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 15.3431543774008 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_b156f382f9cb7c14ad0f69e4", + "semantic_fact_key": "ledger_semantic_fact_v2_3d66fc154a46bcf68776f628", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_60_to_69.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_60_to_69", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "60 to 69", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 28.1946082651287 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_44b3277d563abaa07acf86e7", + "semantic_fact_key": "ledger_semantic_fact_v2_feea5555fbdce74c344dafe8", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.age_70_and_over.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "age_70_and_over", + "table_record_kind": "detail" + }, + "dimensions": { + "age_band": "70 and over", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 36.2889056732402 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_3081efae57a88fe2717e73c4", + "semantic_fact_key": "ledger_semantic_fact_v2_3d966a9987304abd4fbebe3b", + "source_record_id": "dft.nts0601a.mode_trips_by_age.cy2025.all_ages.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0601a.mode_trips_by_age.cy2025", + "groupby_dimension": "dft.age_band", + "groupby_value_id": "all_ages", + "table_record_kind": "total" + }, + "dimensions": { + "age_band": "All Ages", + "sex": "All people" + }, + "source": { + "source_name": "dft", + "source_table": "NTS0601a: Average number of trips by sex, age and main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0601.ods", + "source_sha256": "9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0601-age-mode-trips-2025/2025/9040dfe7e68231f1d1271e349a369ac47b8c78d1f9299ac3bc705b2682ebf1b3/nts0601.ods" + }, + "value": 27.7152103800693 + }, + { + "aggregate_fact_key": "ledger_aggregate_fact_v2_4263895652b50576febaeb0f", + "semantic_fact_key": "ledger_semantic_fact_v2_ebf2299c1cf539491de1c871", + "source_record_id": "dft.nts0303a.mode_trips.cy2025.cy2025.other_local_bus_trips_per_person", + "concept": "dft.other_local_bus_trips_per_person", + "measure_id": "other_local_bus_trips_per_person", + "unit": "trips_per_person_per_year", + "aggregation": "mean", + "entity": { + "name": "person", + "role": "resident_population" + }, + "geography": { + "id": "E92000001", + "level": "country", + "vintage": "current" + }, + "period": { + "type": "calendar_year", + "value": 2025 + }, + "period_coverage": { + "start_date": "2025-01-01", + "end_date": "2025-12-31", + "basis": "survey_reference" + }, + "layout": { + "record_set_id": "dft.nts0303a.mode_trips.cy2025", + "groupby_dimension": "dft.survey_year", + "groupby_value_id": "cy2025", + "table_record_kind": "total" + }, + "dimensions": {}, + "source": { + "source_name": "dft", + "source_table": "NTS0303a: Average number of trips by main mode (trips per person per year): England, 2002 onwards", + "source_file": "nts0303.ods", + "source_sha256": "6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7", + "vintage": "2025", + "raw_r2_key": "raw/uk/dft/dft-nts0303-mode-trips-2025/2025/6dee1fabbae1721674f5298c83df4d66b72b0fe5c49dcbca7952b80677ae00a7/nts0303.ods" + }, + "value": 27.7152103800693 + } + ] +} diff --git a/packages/microcosm-build/src/microcosm/build/uk/ofgem_price_cap_facts.json b/packages/microcosm-build/src/microcosm/build/uk/ofgem_price_cap_facts.json index cf30e8d11..2b2071817 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ofgem_price_cap_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ofgem_price_cap_facts.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/ons_household_expenditure_facts.json b/packages/microcosm-build/src/microcosm/build/uk/ons_household_expenditure_facts.json index 2e8f6aaa2..18ed385bc 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ons_household_expenditure_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ons_household_expenditure_facts.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/orr_rail_facts.json b/packages/microcosm-build/src/microcosm/build/uk/orr_rail_facts.json index 5f5e401ea..eb894a294 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/orr_rail_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/orr_rail_facts.json @@ -17,12 +17,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/qep_energy_prices.json b/packages/microcosm-build/src/microcosm/build/uk/qep_energy_prices.json index 28833abbd..35f58ce32 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/qep_energy_prices.json +++ b/packages/microcosm-build/src/microcosm/build/uk/qep_energy_prices.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/road_fuel_anchors.json b/packages/microcosm-build/src/microcosm/build/uk/road_fuel_anchors.json index 1f993775f..b4020f2b4 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/road_fuel_anchors.json +++ b/packages/microcosm-build/src/microcosm/build/uk/road_fuel_anchors.json @@ -17,12 +17,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json b/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json index 881be3965..f92a0f9ac 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json +++ b/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json @@ -1,13 +1,13 @@ { - "source_fact_feed": "chronicle-uk-c5e5bf8a-consumer-facts", + "source_fact_feed": "chronicle-uk-78466057-consumer-facts", "target_period": 2025, - "candidate_count": 725, - "contract_target_count": 256, - "active_reference_count": 705, + "candidate_count": 646, + "contract_target_count": 247, + "active_reference_count": 631, "status_counts": { - "active": 705, + "active": 631, "no_fact_at_or_before_period": 7, - "signed_excluded": 13 + "signed_excluded": 8 }, "geography_pins": { "obr.income_tax": { @@ -2095,138 +2095,6 @@ "dwp.benefit_cap.capped_households_1300_01_and_above": { "geography_level": "country", "geography_id": "K03000001" - }, - "hmrc.cgt.taxpayers_by_age_band": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.gains_by_age_band": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.tax_by_age_band": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.taxpayers_by_region": { - "geography_fanout": [ - { - "geography_level": "region", - "geography_id": "E12000001" - }, - { - "geography_level": "region", - "geography_id": "E12000002" - }, - { - "geography_level": "region", - "geography_id": "E12000003" - }, - { - "geography_level": "region", - "geography_id": "E12000004" - }, - { - "geography_level": "region", - "geography_id": "E12000005" - }, - { - "geography_level": "region", - "geography_id": "E12000006" - }, - { - "geography_level": "region", - "geography_id": "E12000007" - }, - { - "geography_level": "region", - "geography_id": "E12000008" - }, - { - "geography_level": "region", - "geography_id": "E12000009" - }, - { - "geography_level": "country", - "geography_id": "W92000004" - }, - { - "geography_level": "country", - "geography_id": "S92000003" - }, - { - "geography_level": "country", - "geography_id": "N92000002" - } - ] - }, - "hmrc.cgt.gains_by_region": { - "geography_fanout": [ - { - "geography_level": "region", - "geography_id": "E12000001" - }, - { - "geography_level": "region", - "geography_id": "E12000002" - }, - { - "geography_level": "region", - "geography_id": "E12000003" - }, - { - "geography_level": "region", - "geography_id": "E12000004" - }, - { - "geography_level": "region", - "geography_id": "E12000005" - }, - { - "geography_level": "region", - "geography_id": "E12000006" - }, - { - "geography_level": "region", - "geography_id": "E12000007" - }, - { - "geography_level": "region", - "geography_id": "E12000008" - }, - { - "geography_level": "region", - "geography_id": "E12000009" - }, - { - "geography_level": "country", - "geography_id": "W92000004" - }, - { - "geography_level": "country", - "geography_id": "S92000003" - }, - { - "geography_level": "country", - "geography_id": "N92000002" - } - ] - }, - "hmrc.cgt.taxpayers_by_gain_band": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.gains_by_gain_band": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.residential_property_taxpayers": { - "geography_level": "country", - "geography_id": "K02000001" - }, - "hmrc.cgt.residential_property_gains": { - "geography_level": "country", - "geography_id": "K02000001" } }, "genuine_sum_residue": [ @@ -5172,9322 +5040,8064 @@ "name": "dwp.benefit_cap.capped_households_1300_01_and_above", "from": "2025-11", "to": "2025" + } + ], + "targets": { + "obr.income_tax": { + "status": "active", + "candidates": [ + { + "name": "obr.income_tax", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 331437583074.4429, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_d928e7da0fbfe088ca1a30d7" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_16_to_24", - "from": "2024", - "to": "2025" + "obr.ni": { + "status": "active", + "candidates": [ + { + "name": "obr.ni", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 200081395082.7125, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_eccab3ee763d68bb782276a7" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_25_to_34", - "from": "2024", - "to": "2025" + "obr.ni_employee": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_employee", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 49544363784.26465, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_7e3e3e637a9134760a0a530a" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_35_to_44", - "from": "2024", - "to": "2025" + "obr.ni_employer": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_employer", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 145324007512.71753, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_c8719021c501d9757e0e0814" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_45_to_54", - "from": "2024", - "to": "2025" + "obr.ni_self_employed": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_self_employed", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 2902816090.4147716, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b94b7d74d7df7ff5f9309f3b" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_55_to_64", - "from": "2024", - "to": "2025" + "obr.vat": { + "status": "active", + "candidates": [ + { + "name": "obr.vat", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 180168938685.41794, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_3c534c3e6313150f8081b777" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_65_to_74", - "from": "2024", - "to": "2025" + "obr.fuel_duties": { + "status": "signed_excluded", + "candidates": [ + { + "name": "obr.fuel_duties", + "status": "signed_excluded", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "signed_rationale": "The OBR fuel duties fact is all-road-users receipts (freight, vans, business mileage) against a household frame; obr.fuel_duties_cars binds the cars receipts from the OBR vehicle-type release instead (ruling 2026-09-10). The all-road-users row is retained in the contract for registry parity and signed out here rather than carried as a calibration measure exclusion." + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_75_to_84", - "from": "2024", - "to": "2025" + "hmrc.cgt.liability_total": { + "status": "active", + "candidates": [ + { + "name": "hmrc.cgt.liability_total", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 22503000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_222c397017de7bff0a6583a7" + } + ] }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_85_plus", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_16_to_24", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_25_to_34", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_35_to_44", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_45_to_54", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_55_to_64", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_65_to_74", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_75_to_84", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_85_plus", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_16_to_24", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_25_to_34", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_35_to_44", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_45_to_54", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_55_to_64", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_65_to_74", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_75_to_84", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_85_plus", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000001", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000002", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000003", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000004", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000005", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000006", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000007", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000008", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@E12000009", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@W92000004", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@S92000003", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.taxpayers_by_region@N92000002", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000001", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000002", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000003", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000004", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000005", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000006", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000007", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000008", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@E12000009", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@W92000004", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@S92000003", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.gains_by_region@N92000002", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_1000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_100000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_10000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_12300", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_2000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_250000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_25000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_3000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_5000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_500000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_50000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/cgt_taxpayers_band_6000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_1000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_100000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_10000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_12300", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_2000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_250000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_25000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_3000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_5000000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_500000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_50000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc/capital_gains_band_6000", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.residential_property_taxpayers.ty2024", - "from": "2024", - "to": "2025" - }, - { - "name": "hmrc.cgt.residential_property_gains.ty2024", - "from": "2024", - "to": "2025" - } - ], - "targets": { - "obr.income_tax": { - "status": "active", - "candidates": [ - { - "name": "obr.income_tax", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 331437583074.4429, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_d928e7da0fbfe088ca1a30d7" - } - ] - }, - "obr.ni": { - "status": "active", - "candidates": [ - { - "name": "obr.ni", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 200081395082.7125, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_eccab3ee763d68bb782276a7" - } - ] - }, - "obr.ni_employee": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_employee", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 49544363784.26465, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_7e3e3e637a9134760a0a530a" - } - ] - }, - "obr.ni_employer": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_employer", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 145324007512.71753, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8719021c501d9757e0e0814" - } - ] - }, - "obr.ni_self_employed": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_self_employed", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 2902816090.4147716, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b94b7d74d7df7ff5f9309f3b" - } - ] - }, - "obr.vat": { - "status": "active", - "candidates": [ - { - "name": "obr.vat", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 180168938685.41794, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c534c3e6313150f8081b777" - } - ] - }, - "obr.fuel_duties": { - "status": "signed_excluded", - "candidates": [ - { - "name": "obr.fuel_duties", - "status": "signed_excluded", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "signed_rationale": "The OBR fuel duties fact is all-road-users receipts (freight, vans, business mileage) against a household frame; obr.fuel_duties_cars binds the cars receipts from the OBR vehicle-type release instead (ruling 2026-09-10). The all-road-users row is retained in the contract for registry parity and signed out here rather than carried as a calibration measure exclusion." - } - ] - }, - "hmrc.cgt.liability_total": { - "status": "active", - "candidates": [ - { - "name": "hmrc.cgt.liability_total", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 22503000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_222c397017de7bff0a6583a7" - } - ] - }, - "obr.sdlt": { - "status": "active", - "candidates": [ - { - "name": "obr.sdlt", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 15406516698.785578, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_1b6d55fc4ccd78bd0ae457e9" - } - ] - }, - "obr.attendance_allowance": { - "status": "active", - "candidates": [ - { - "name": "obr.attendance_allowance", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 8492497075.074617, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4fe1b1966eeb22c0c5ca464c" - } - ] - }, - "obr.carers_allowance": { - "status": "active", - "candidates": [ - { - "name": "obr.carers_allowance", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 4569403813.760573, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_ca7be49d51152bcc4c6662f2" - } - ] - }, - "obr.child_benefit": { - "status": "active", - "candidates": [ - { - "name": "obr.child_benefit", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 13389272724.45089, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_d3ab2c54ce0c4c6a46a7a36b" - } - ] - }, - "obr.council_tax": { - "status": "active", - "candidates": [ - { - "name": "obr.council_tax", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 50925163826.30539, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_16bcd3e2a16bfa44c0b1ea74" - } - ] - }, - "obr.council_tax_england": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "obr.council_tax_england", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "obr.council_tax_scotland": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "obr.council_tax_scotland", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "obr.council_tax_wales": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "obr.council_tax_wales", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "obr.domestic_rates": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "obr.domestic_rates", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "obr.esa": { - "status": "active", - "candidates": [ - { - "name": "obr.esa", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 7206287181.538654, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_632a67850494984d9b35e639" - } - ] - }, - "obr.housing_benefit": { - "status": "active", - "candidates": [ - { - "name": "obr.housing_benefit", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 12103254163.788864, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_984cc88cfc4242bd80c679f3" - } - ] - }, - "obr.jobseekers_allowance": { - "status": "active", - "candidates": [ - { - "name": "obr.jobseekers_allowance", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 280558748.04472804, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_d505f8a08a29411dcf69287b" - } - ] - }, - "obr.pension_credit": { - "status": "active", - "candidates": [ - { - "name": "obr.pension_credit", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 6146422389.476461, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_95ea9bc008361c26f90591d4" - } - ] - }, - "obr.pip": { - "status": "active", - "candidates": [ - { - "name": "obr.pip", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 36910059270.5278, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_548ebadeb7d774b32fa6f4ff" - } - ] - }, - "obr.state_pension": { - "status": "active", - "candidates": [ - { - "name": "obr.state_pension", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 146185954351.57382, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_567e55f9f73df2808c1c4be8" - } - ] - }, - "obr.statutory_maternity_pay": { - "status": "active", - "candidates": [ - { - "name": "obr.statutory_maternity_pay", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 3194800881.520547, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_0c45b526e2b233b22d955cc6" - } - ] - }, - "obr.tv_licence_fee": { - "status": "active", - "candidates": [ - { - "name": "obr.tv_licence_fee", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 3872000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b0f0afcd44c93532837c9f2a" - } - ] - }, - "obr.universal_credit_in_cap": { - "status": "active", - "candidates": [ - { - "name": "obr.universal_credit_in_cap", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 66410800011.47837, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" - } - ] - }, - "obr.universal_credit_outside_cap": { - "status": "active", - "candidates": [ - { - "name": "obr.universal_credit_outside_cap", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 12875549128.065746, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4c927d7b33d1eee2455bdbd0" - } - ] - }, - "obr.winter_fuel_allowance": { - "status": "active", - "candidates": [ - { - "name": "obr.winter_fuel_allowance", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 1911040880.4619167, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_575778670363b5890c8de847" - } - ] - }, - "isc.private_school_students": { - "status": "active", - "candidates": [ - { - "name": "isc.private_school_students", - "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 556551.0, - "resolved_fact_period": "2024-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_67bd24e7f9158af756625865" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_basic_rate": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.it_relief_basic_rate", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 1600000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7320889e57785e6997224191" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_higher_rate": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.it_relief_higher_rate", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 5500000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7d9ff26814151157071301e9" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_additional_rate": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.it_relief_additional_rate", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 1800000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_49a712ba4b22f0b4b2925ef9" - } - ] - }, - "hmrc.salary_sacrifice.nics_relief_employee": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.nics_relief_employee", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 1000000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_341767859ef6030c06c7a153" - } - ] - }, - "hmrc.salary_sacrifice.nics_relief_employer": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.nics_relief_employer", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3400000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_026ae1169f5f0f997bb06479" - } - ] - }, - "hmrc.salary_sacrifice.users_total": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.users_total", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 7700000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_06d585b8684b5fe0ce25f6ec" - } - ] - }, - "hmrc.salary_sacrifice.users_below_cap": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.users_below_cap", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4300000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_a48e584180a6f33d07112d3c" - } - ] - }, - "hmrc.salary_sacrifice.users_above_cap": { - "status": "active", - "candidates": [ - { - "name": "hmrc.salary_sacrifice.users_above_cap", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3300000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_0331d77688891a3c3c3307b6" - } - ] - }, - "hmrc.spi.employment_income.amount_by_total_income_band": { - "status": "active", - "candidates": [ - { - "name": "hmrc/employment_income_income_band_100_000_to_150_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 82300000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b1c634a871c843888ab00545" - }, - { - "name": "hmrc/employment_income_income_band_1_000_000_to_inf", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 35500000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_16019afa59e224b690877826" - }, - { - "name": "hmrc/employment_income_income_band_12_570_to_15_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 16900000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a82c84f67b40867564d2c847" - }, - { - "name": "hmrc/employment_income_income_band_15_000_to_20_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 48600000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_42eb325b6a29afb3e6d157fa" - }, - { - "name": "hmrc/employment_income_income_band_150_000_to_200_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 39200000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1f93702eb88f381f0701c4f8" - }, - { - "name": "hmrc/employment_income_income_band_20_000_to_30_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 172000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_794fd9633d6a2018fee633e7" - }, - { - "name": "hmrc/employment_income_income_band_200_000_to_300_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 36600000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d85ad655daaa164b1ab33231" - }, - { - "name": "hmrc/employment_income_income_band_30_000_to_40_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 170000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3607635c72d16b4059b6a3f6" - }, - { - "name": "hmrc/employment_income_income_band_300_000_to_500_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 29000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5c3674b48269ffe3c7b28a1b" - }, - { - "name": "hmrc/employment_income_income_band_40_000_to_50_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 139000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_525aeb02ab9a831608756200" - }, - { - "name": "hmrc/employment_income_income_band_50_000_to_70_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 174000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_9f1a70b4e0995af34d7dbbfb" - }, - { - "name": "hmrc/employment_income_income_band_500_000_to_1_000_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 23100000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1944a2f33309b41b2d5f348d" - }, - { - "name": "hmrc/employment_income_income_band_70_000_to_100_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 118000000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6178d003a4c1a6198294f174" - } - ] - }, - "hmrc.spi.employment_income.count_by_total_income_band": { - "status": "active", - "candidates": [ - { - "name": "hmrc/employment_income_count_income_band_100_000_to_150_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 791000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b83fec2e722ef22cbe28ee76" - }, - { - "name": "hmrc/employment_income_count_income_band_1_000_000_to_inf", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 21000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_618b4f84a2b10fdf0d901df6" - }, - { - "name": "hmrc/employment_income_count_income_band_12_570_to_15_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 1360000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5a2e006ccd94f8754760661c" - }, - { - "name": "hmrc/employment_income_count_income_band_15_000_to_20_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3100000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a4ecaa65aa113092a1c8fcf7" - }, - { - "name": "hmrc/employment_income_count_income_band_150_000_to_200_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 264000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffcb46afae1c469de75ee9b3" - }, - { - "name": "hmrc/employment_income_count_income_band_20_000_to_30_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 7470000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1bbafa142b4bfc426ce5bdac" - }, - { - "name": "hmrc/employment_income_count_income_band_200_000_to_300_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 180000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd00b1e66c3254ddc0e108a6" - }, - { - "name": "hmrc/employment_income_count_income_band_30_000_to_40_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 5370000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3bd51396d03aee4164d7c1d6" - }, - { - "name": "hmrc/employment_income_count_income_band_300_000_to_500_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 93000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d1f4ceb7f4e676d9ff044d80" - }, - { - "name": "hmrc/employment_income_count_income_band_40_000_to_50_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3500000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_874b13ae1da1064e73055c39" - }, - { - "name": "hmrc/employment_income_count_income_band_50_000_to_70_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3430000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_572104f32689df4a2dc4c334" - }, - { - "name": "hmrc/employment_income_count_income_band_500_000_to_1_000_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 44000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b99d6944753bf5696bdc8f9" - }, - { - "name": "hmrc/employment_income_count_income_band_70_000_to_100_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 1640000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8eec35d25c57e9c2e2c7962b" - } - ] - }, - "hmrc.spi.self_employment_income.amount_by_total_income_band": { - "status": "active", - "candidates": [ - { - "name": "hmrc/self_employment_income_income_band_100_000_to_150_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4980000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5b616c7ebeb21ef5305b8beb" - }, - { - "name": "hmrc/self_employment_income_income_band_1_000_000_to_inf", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 19500000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_761827852b6a2fccb3d15132" - }, - { - "name": "hmrc/self_employment_income_income_band_12_570_to_15_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4810000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1a69068db718770de7df525e" - }, - { - "name": "hmrc/self_employment_income_income_band_15_000_to_20_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 8030000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c1df7ca022a9c007f122de6d" - }, - { - "name": "hmrc/self_employment_income_income_band_150_000_to_200_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3650000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7183b7c143f8e897552ad685" - }, - { - "name": "hmrc/self_employment_income_income_band_20_000_to_30_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 15700000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_33c4f0779c40ec91ff6761da" - }, - { - "name": "hmrc/self_employment_income_income_band_200_000_to_300_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4390000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_90652f32ebe0ff36c569998d" - }, - { - "name": "hmrc/self_employment_income_income_band_30_000_to_40_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 12600000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1b9ad3f39e949b92a26ec28c" - }, - { - "name": "hmrc/self_employment_income_income_band_300_000_to_500_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4840000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f921ffdb56a575057076f8" - }, - { - "name": "hmrc/self_employment_income_income_band_40_000_to_50_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 8730000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_645090db5db62f7c47a34f60" - }, - { - "name": "hmrc/self_employment_income_income_band_50_000_to_70_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 8220000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0d7af3458463a645af3cb76" - }, - { - "name": "hmrc/self_employment_income_income_band_500_000_to_1_000_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 6670000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc7a985c6a2a3d69e2c9ae75" - }, - { - "name": "hmrc/self_employment_income_income_band_70_000_to_100_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 5360000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c588886840e4e7e4a141ac75" - } - ] - }, - "hmrc.spi.self_employment_income.count_by_total_income_band": { - "status": "active", - "candidates": [ - { - "name": "hmrc/self_employment_income_count_income_band_100_000_to_150_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 85000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_db16ef55b3b0f60d292b745b" - }, - { - "name": "hmrc/self_employment_income_count_income_band_1_000_000_to_inf", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 11000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_315a063dab8497ed5b8837b6" - }, - { - "name": "hmrc/self_employment_income_count_income_band_12_570_to_15_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 444000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_498ad10a35b58ff55819bc8b" - }, - { - "name": "hmrc/self_employment_income_count_income_band_15_000_to_20_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 651000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb849a98f57c60bd507d621b" - }, - { - "name": "hmrc/self_employment_income_count_income_band_150_000_to_200_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 40000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_cfb6ca3c4eff6a83bd5c10ac" - }, - { - "name": "hmrc/self_employment_income_count_income_band_20_000_to_30_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 961000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_72bd71f362434b2260a4b407" - }, - { - "name": "hmrc/self_employment_income_count_income_band_200_000_to_300_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 34000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe86d957cb9590b3292e1757" - }, - { - "name": "hmrc/self_employment_income_count_income_band_30_000_to_40_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 595000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_84b75f0a77e11de0182b9d87" - }, - { - "name": "hmrc/self_employment_income_count_income_band_300_000_to_500_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 21000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5c668fd92047d28d73d7c36d" - }, - { - "name": "hmrc/self_employment_income_count_income_band_40_000_to_50_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 359000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_876b5e55461ed15a7456d8b3" - }, - { - "name": "hmrc/self_employment_income_count_income_band_50_000_to_70_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 311000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_09e5a5c61ccf990f6104a903" - }, + "obr.sdlt": { + "status": "active", + "candidates": [ { - "name": "hmrc/self_employment_income_count_income_band_500_000_to_1_000_000", + "name": "obr.sdlt", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 15000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73031eb82b28c872e4371fae" - }, + "resolved_value": 15406516698.785578, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_1b6d55fc4ccd78bd0ae457e9" + } + ] + }, + "obr.attendance_allowance": { + "status": "active", + "candidates": [ { - "name": "hmrc/self_employment_income_count_income_band_70_000_to_100_000", + "name": "obr.attendance_allowance", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 143000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c35c3f72e5f7901457970c8d" + "resolved_value": 8492497075.074617, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4fe1b1966eeb22c0c5ca464c" } ] }, - "hmrc.spi.dividend_income.amount_by_total_income_band": { + "obr.carers_allowance": { "status": "active", "candidates": [ { - "name": "hmrc/dividend_income_income_band_100_000_to_150_000", + "name": "obr.carers_allowance", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 6870000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6fd01f132dc6b218c02326b1" - }, + "resolved_value": 4569403813.760573, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_ca7be49d51152bcc4c6662f2" + } + ] + }, + "obr.child_benefit": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_1_000_000_to_inf", + "name": "obr.child_benefit", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 11100000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c0cd54a0f0609d8ebc58a25" - }, + "resolved_value": 13389272724.45089, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_d3ab2c54ce0c4c6a46a7a36b" + } + ] + }, + "obr.council_tax": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_12_570_to_15_000", + "name": "obr.council_tax", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 175000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b63a84056f85bed14b8ab8fd" - }, + "resolved_value": 50925163826.30539, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_16bcd3e2a16bfa44c0b1ea74" + } + ] + }, + "obr.council_tax_england": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_15_000_to_20_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 855000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c4f22fc63944665033b18b3" - }, + "name": "obr.council_tax_england", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.council_tax_scotland": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_150_000_to_200_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3450000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ced1a5840ced099b471d4e84" - }, + "name": "obr.council_tax_scotland", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.council_tax_wales": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_20_000_to_30_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3330000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8a115e840b38a6603d618bc0" - }, + "name": "obr.council_tax_wales", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.domestic_rates": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_200_000_to_300_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 3700000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0394e55216df7f3dcab84fb5" - }, + "name": "obr.domestic_rates", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.esa": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_30_000_to_40_000", + "name": "obr.esa", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 4700000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ea93d59adaf66ef73e9dddbf" - }, + "resolved_value": 7206287181.538654, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_632a67850494984d9b35e639" + } + ] + }, + "obr.housing_benefit": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_300_000_to_500_000", + "name": "obr.housing_benefit", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 3430000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8d09d2287cbdb2e4f4004521" - }, + "resolved_value": 12103254163.788864, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_984cc88cfc4242bd80c679f3" + } + ] + }, + "obr.jobseekers_allowance": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_40_000_to_50_000", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "name": "obr.jobseekers_allowance", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 8400000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a4329a3eb027a530c6f02ec" - }, + "resolved_value": 280558748.04472804, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_d505f8a08a29411dcf69287b" + } + ] + }, + "obr.pension_credit": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_50_000_to_70_000", + "name": "obr.pension_credit", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 12500000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c11497ffe45250b909593f1d" - }, + "resolved_value": 6146422389.476461, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_95ea9bc008361c26f90591d4" + } + ] + }, + "obr.pip": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_500_000_to_1_000_000", + "name": "obr.pip", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 3820000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_dafc8ca1cd03e5d461b11d4e" - }, + "resolved_value": 36910059270.5278, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_548ebadeb7d774b32fa6f4ff" + } + ] + }, + "obr.state_pension": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_income_band_70_000_to_100_000", + "name": "obr.state_pension", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 9440000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_940e6ce9db10080ed5613faa" + "resolved_value": 146185954351.57382, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_567e55f9f73df2808c1c4be8" } ] }, - "hmrc.spi.dividend_income.count_by_total_income_band": { + "obr.statutory_maternity_pay": { "status": "active", "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_100_000_to_150_000", + "name": "obr.statutory_maternity_pay", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 222000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_35b535ef60b7e9e8ddad45af" - }, + "resolved_value": 3194800881.520547, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_0c45b526e2b233b22d955cc6" + } + ] + }, + "obr.tv_licence_fee": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_1_000_000_to_inf", + "name": "obr.tv_licence_fee", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 19000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbe097b0ffbcc0e7a301478d" - }, + "resolved_value": 3872000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b0f0afcd44c93532837c9f2a" + } + ] + }, + "obr.universal_credit_in_cap": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_12_570_to_15_000", + "name": "obr.universal_credit_in_cap", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 115000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3a657db84b033007853ec14b" - }, + "resolved_value": 66410800011.47837, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" + } + ] + }, + "obr.universal_credit_outside_cap": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_15_000_to_20_000", + "name": "obr.universal_credit_outside_cap", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 372000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_418541677821ff087753a7b4" - }, + "resolved_value": 12875549128.065746, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4c927d7b33d1eee2455bdbd0" + } + ] + }, + "obr.winter_fuel_allowance": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_150_000_to_200_000", + "name": "obr.winter_fuel_allowance", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 92000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_426db10645b611899a770dbd" - }, + "resolved_value": 1911040880.4619167, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_575778670363b5890c8de847" + } + ] + }, + "isc.private_school_students": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_20_000_to_30_000", + "name": "isc.private_school_students", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 843000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_937f405149e37c0c900a62ee" - }, + "resolved_value": 556551.0, + "resolved_fact_period": "2024-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_67bd24e7f9158af756625865" + } + ] + }, + "hmrc.salary_sacrifice.it_relief_basic_rate": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_200_000_to_300_000", + "name": "hmrc.salary_sacrifice.it_relief_basic_rate", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 75000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6c0e32c82b968ba545457cab" - }, + "resolved_value": 1600000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7320889e57785e6997224191" + } + ] + }, + "hmrc.salary_sacrifice.it_relief_higher_rate": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_30_000_to_40_000", + "name": "hmrc.salary_sacrifice.it_relief_higher_rate", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 667000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8fc2a8e3993c51b68cc6f8a" - }, + "resolved_value": 5500000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7d9ff26814151157071301e9" + } + ] + }, + "hmrc.salary_sacrifice.it_relief_additional_rate": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_300_000_to_500_000", + "name": "hmrc.salary_sacrifice.it_relief_additional_rate", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 49000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_439d9908bf6880e33103ea7d" - }, + "resolved_value": 1800000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_49a712ba4b22f0b4b2925ef9" + } + ] + }, + "hmrc.salary_sacrifice.nics_relief_employee": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_40_000_to_50_000", + "name": "hmrc.salary_sacrifice.nics_relief_employee", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 627000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_60bb54980a6ca69ff77d07f0" - }, + "resolved_value": 1000000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_341767859ef6030c06c7a153" + } + ] + }, + "hmrc.salary_sacrifice.nics_relief_employer": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_50_000_to_70_000", + "name": "hmrc.salary_sacrifice.nics_relief_employer", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 643000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_56b8b1dd7aec08c3abddc3a0" - }, + "resolved_value": 3400000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_026ae1169f5f0f997bb06479" + } + ] + }, + "hmrc.salary_sacrifice.users_total": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc.salary_sacrifice.users_total", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 32000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c9f024b8595617fc8dd8e416" - }, + "resolved_value": 7700000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_06d585b8684b5fe0ce25f6ec" + } + ] + }, + "hmrc.salary_sacrifice.users_below_cap": { + "status": "active", + "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_70_000_to_100_000", + "name": "hmrc.salary_sacrifice.users_below_cap", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 336000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ed13533e012fdd1fec68a67" + "resolved_value": 4300000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_a48e584180a6f33d07112d3c" } ] }, - "hmrc.spi.property_income.amount_by_total_income_band": { - "status": "signed_excluded", + "hmrc.salary_sacrifice.users_above_cap": { + "status": "active", "candidates": [ { - "name": "hmrc.spi.property_income.amount_by_total_income_band", - "status": "signed_excluded", - "matched_fact_count_overall": 13, - "matched_fact_count_at_or_before_period": 13, - "signed_rationale": "Signed out pending a first-class value-scaling operation or a Chronicle package for HMRC Property Rental Income Statistics with declared reconciliation: the Ledger facts are official HMRC SPI Table 3.7 net property-income amounts, while the incumbent calibration target applies the populace-side x1.9 property-income undercount adjustment. The x1.9 trace is uk-data PR #311 / issue uk-data#230: SPI covers only taxpayers with liability, and HMRC Property Rental Income Statistics show GBP 46.68bn versus SPI about GBP 24.5bn for 2020-21. Binding the raw SPI facts would knowingly calibrate to 10/19 of the incumbent surface." + "name": "hmrc.salary_sacrifice.users_above_cap", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 3300000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_0331d77688891a3c3c3307b6" } ] }, - "hmrc.spi.property_income.count_by_total_income_band": { + "hmrc.spi.employment_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/property_income_count_income_band_100_000_to_150_000", + "name": "hmrc/employment_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 137000.0, + "resolved_value": 82300000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_50e02eb85969a4773af5cade" + "resolved_fact_key": "ledger_aggregate_fact_v2_b1c634a871c843888ab00545" }, { - "name": "hmrc/property_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/employment_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7000.0, + "resolved_value": 35500000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d286366fea43c9f897936709" + "resolved_fact_key": "ledger_aggregate_fact_v2_16019afa59e224b690877826" }, { - "name": "hmrc/property_income_count_income_band_12_570_to_15_000", + "name": "hmrc/employment_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 101000.0, + "resolved_value": 16900000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_80d817cee2f3592809f3a194" + "resolved_fact_key": "ledger_aggregate_fact_v2_a82c84f67b40867564d2c847" }, { - "name": "hmrc/property_income_count_income_band_15_000_to_20_000", + "name": "hmrc/employment_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 232000.0, + "resolved_value": 48600000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2c0d78b9f9dff4e5fdfa250c" + "resolved_fact_key": "ledger_aggregate_fact_v2_42eb325b6a29afb3e6d157fa" }, { - "name": "hmrc/property_income_count_income_band_150_000_to_200_000", + "name": "hmrc/employment_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 54000.0, + "resolved_value": 39200000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5ec672db73bb4f35958a409e" + "resolved_fact_key": "ledger_aggregate_fact_v2_1f93702eb88f381f0701c4f8" }, { - "name": "hmrc/property_income_count_income_band_20_000_to_30_000", + "name": "hmrc/employment_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 431000.0, + "resolved_value": 172000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3eb40c70c3de0d0c29253566" + "resolved_fact_key": "ledger_aggregate_fact_v2_794fd9633d6a2018fee633e7" }, { - "name": "hmrc/property_income_count_income_band_200_000_to_300_000", + "name": "hmrc/employment_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 41000.0, + "resolved_value": 36600000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0394669c5734865fda5f0541" + "resolved_fact_key": "ledger_aggregate_fact_v2_d85ad655daaa164b1ab33231" }, { - "name": "hmrc/property_income_count_income_band_30_000_to_40_000", + "name": "hmrc/employment_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 364000.0, + "resolved_value": 170000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6564bb4b662365729676a9e1" + "resolved_fact_key": "ledger_aggregate_fact_v2_3607635c72d16b4059b6a3f6" }, { - "name": "hmrc/property_income_count_income_band_300_000_to_500_000", + "name": "hmrc/employment_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 23000.0, + "resolved_value": 29000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_87c457b7ee2392ee8360893b" + "resolved_fact_key": "ledger_aggregate_fact_v2_5c3674b48269ffe3c7b28a1b" }, { - "name": "hmrc/property_income_count_income_band_40_000_to_50_000", + "name": "hmrc/employment_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 325000.0, + "resolved_value": 139000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7187a98d8342886b08e3f9e2" + "resolved_fact_key": "ledger_aggregate_fact_v2_525aeb02ab9a831608756200" }, { - "name": "hmrc/property_income_count_income_band_50_000_to_70_000", + "name": "hmrc/employment_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 397000.0, + "resolved_value": 174000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c44a33c3bc4454de20132027" + "resolved_fact_key": "ledger_aggregate_fact_v2_9f1a70b4e0995af34d7dbbfb" }, { - "name": "hmrc/property_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/employment_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13000.0, + "resolved_value": 23100000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_831e0c70ca80d37c785d4122" + "resolved_fact_key": "ledger_aggregate_fact_v2_1944a2f33309b41b2d5f348d" }, { - "name": "hmrc/property_income_count_income_band_70_000_to_100_000", + "name": "hmrc/employment_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 226000.0, + "resolved_value": 118000000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f93d04a399cee892e5ec86b6" + "resolved_fact_key": "ledger_aggregate_fact_v2_6178d003a4c1a6198294f174" } ] }, - "hmrc.spi.private_pension_income.amount_by_total_income_band": { + "hmrc.spi.employment_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/private_pension_income_income_band_100_000_to_150_000", + "name": "hmrc/employment_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5430000000.0, + "resolved_value": 791000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_cb943439ee9edfb445bc3fa5" + "resolved_fact_key": "ledger_aggregate_fact_v2_b83fec2e722ef22cbe28ee76" }, { - "name": "hmrc/private_pension_income_income_band_1_000_000_to_inf", + "name": "hmrc/employment_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 370000000.0, + "resolved_value": 21000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7dcf8568040de10d9b3765da" + "resolved_fact_key": "ledger_aggregate_fact_v2_618b4f84a2b10fdf0d901df6" }, { - "name": "hmrc/private_pension_income_income_band_12_570_to_15_000", + "name": "hmrc/employment_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4350000000.0, + "resolved_value": 1360000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_699889c2fb48479e27e44a4a" + "resolved_fact_key": "ledger_aggregate_fact_v2_5a2e006ccd94f8754760661c" }, { - "name": "hmrc/private_pension_income_income_band_15_000_to_20_000", + "name": "hmrc/employment_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13600000000.0, + "resolved_value": 3100000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0f977d0b50c1d0f1d1364e88" + "resolved_fact_key": "ledger_aggregate_fact_v2_a4ecaa65aa113092a1c8fcf7" }, { - "name": "hmrc/private_pension_income_income_band_150_000_to_200_000", + "name": "hmrc/employment_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1810000000.0, + "resolved_value": 264000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d29aac0680380c80bd842bae" + "resolved_fact_key": "ledger_aggregate_fact_v2_ffcb46afae1c469de75ee9b3" }, { - "name": "hmrc/private_pension_income_income_band_20_000_to_30_000", + "name": "hmrc/employment_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 30200000000.0, + "resolved_value": 7470000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_bafcebe21a05cb0ca19d5e4f" + "resolved_fact_key": "ledger_aggregate_fact_v2_1bbafa142b4bfc426ce5bdac" }, { - "name": "hmrc/private_pension_income_income_band_200_000_to_300_000", + "name": "hmrc/employment_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1570000000.0, + "resolved_value": 180000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_de0ed091681463c4ddec5b85" + "resolved_fact_key": "ledger_aggregate_fact_v2_dd00b1e66c3254ddc0e108a6" }, { - "name": "hmrc/private_pension_income_income_band_30_000_to_40_000", + "name": "hmrc/employment_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 24900000000.0, + "resolved_value": 5370000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2884a006a8d7c144a8570a7d" + "resolved_fact_key": "ledger_aggregate_fact_v2_3bd51396d03aee4164d7c1d6" }, { - "name": "hmrc/private_pension_income_income_band_300_000_to_500_000", + "name": "hmrc/employment_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1120000000.0, + "resolved_value": 93000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73e8de3b1ac198cc75c2b696" + "resolved_fact_key": "ledger_aggregate_fact_v2_d1f4ceb7f4e676d9ff044d80" }, { - "name": "hmrc/private_pension_income_income_band_40_000_to_50_000", + "name": "hmrc/employment_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16900000000.0, + "resolved_value": 3500000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6b29cd5a1d665a00bb3e8046" + "resolved_fact_key": "ledger_aggregate_fact_v2_874b13ae1da1064e73055c39" }, { - "name": "hmrc/private_pension_income_income_band_50_000_to_70_000", + "name": "hmrc/employment_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 17400000000.0, + "resolved_value": 3430000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8f911d955de4f80e87dc69d8" + "resolved_fact_key": "ledger_aggregate_fact_v2_572104f32689df4a2dc4c334" }, { - "name": "hmrc/private_pension_income_income_band_500_000_to_1_000_000", + "name": "hmrc/employment_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 640000000.0, + "resolved_value": 44000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a13e6165bec82537c5c2883c" + "resolved_fact_key": "ledger_aggregate_fact_v2_3b99d6944753bf5696bdc8f9" }, { - "name": "hmrc/private_pension_income_income_band_70_000_to_100_000", + "name": "hmrc/employment_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9470000000.0, + "resolved_value": 1640000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a1db235b87cad00eeddbfd8" + "resolved_fact_key": "ledger_aggregate_fact_v2_8eec35d25c57e9c2e2c7962b" } ] }, - "hmrc.spi.private_pension_income.count_by_total_income_band": { + "hmrc.spi.self_employment_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/private_pension_income_count_income_band_100_000_to_150_000", + "name": "hmrc/self_employment_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 109000.0, + "resolved_value": 4980000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1fa1ba97628c6c2c315f0e15" + "resolved_fact_key": "ledger_aggregate_fact_v2_5b616c7ebeb21ef5305b8beb" }, { - "name": "hmrc/private_pension_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/self_employment_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2000.0, + "resolved_value": 19500000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_188f8f1a0535263e4db7c9a8" + "resolved_fact_key": "ledger_aggregate_fact_v2_761827852b6a2fccb3d15132" }, { - "name": "hmrc/private_pension_income_count_income_band_12_570_to_15_000", + "name": "hmrc/self_employment_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1070000.0, + "resolved_value": 4810000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_853f104082cf479b98952c1a" + "resolved_fact_key": "ledger_aggregate_fact_v2_1a69068db718770de7df525e" }, { - "name": "hmrc/private_pension_income_count_income_band_15_000_to_20_000", + "name": "hmrc/self_employment_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2140000.0, + "resolved_value": 8030000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c785199ee1d08fabfe927ff0" + "resolved_fact_key": "ledger_aggregate_fact_v2_c1df7ca022a9c007f122de6d" }, { - "name": "hmrc/private_pension_income_count_income_band_150_000_to_200_000", + "name": "hmrc/self_employment_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 29000.0, + "resolved_value": 3650000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a98ec830dee0eceb16b452e7" + "resolved_fact_key": "ledger_aggregate_fact_v2_7183b7c143f8e897552ad685" }, { - "name": "hmrc/private_pension_income_count_income_band_20_000_to_30_000", + "name": "hmrc/self_employment_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2660000.0, + "resolved_value": 15700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1df6f17a33011c1c026dbc09" + "resolved_fact_key": "ledger_aggregate_fact_v2_33c4f0779c40ec91ff6761da" }, { - "name": "hmrc/private_pension_income_count_income_band_200_000_to_300_000", + "name": "hmrc/self_employment_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 20000.0, + "resolved_value": 4390000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_042ab8896eb0214e7bbad477" + "resolved_fact_key": "ledger_aggregate_fact_v2_90652f32ebe0ff36c569998d" }, { - "name": "hmrc/private_pension_income_count_income_band_30_000_to_40_000", + "name": "hmrc/self_employment_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1450000.0, + "resolved_value": 12600000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a28fd76533fc93cf8dbfe4a" + "resolved_fact_key": "ledger_aggregate_fact_v2_1b9ad3f39e949b92a26ec28c" }, { - "name": "hmrc/private_pension_income_count_income_band_300_000_to_500_000", + "name": "hmrc/self_employment_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 10000.0, + "resolved_value": 4840000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7fccfc3ee4246841b3ed391b" + "resolved_fact_key": "ledger_aggregate_fact_v2_96f921ffdb56a575057076f8" }, { - "name": "hmrc/private_pension_income_count_income_band_40_000_to_50_000", + "name": "hmrc/self_employment_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 779000.0, + "resolved_value": 8730000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0f808aa135a13e5aa4668d22" + "resolved_fact_key": "ledger_aggregate_fact_v2_645090db5db62f7c47a34f60" }, { - "name": "hmrc/private_pension_income_count_income_band_50_000_to_70_000", + "name": "hmrc/self_employment_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 643000.0, + "resolved_value": 8220000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_097efdacf2adf0f90f90d1de" + "resolved_fact_key": "ledger_aggregate_fact_v2_f0d7af3458463a645af3cb76" }, { - "name": "hmrc/private_pension_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/self_employment_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4000.0, + "resolved_value": 6670000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8abdd0aa368c3d693e6d0989" + "resolved_fact_key": "ledger_aggregate_fact_v2_fc7a985c6a2a3d69e2c9ae75" }, { - "name": "hmrc/private_pension_income_count_income_band_70_000_to_100_000", + "name": "hmrc/self_employment_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 259000.0, + "resolved_value": 5360000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f75fc4c3e2cb06bbdb7543f8" + "resolved_fact_key": "ledger_aggregate_fact_v2_c588886840e4e7e4a141ac75" } ] }, - "hmrc.spi.state_pension.amount_by_total_income_band": { + "hmrc.spi.self_employment_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/state_pension_income_band_100_000_to_150_000", + "name": "hmrc/self_employment_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 847000000.0, + "resolved_value": 85000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d63e1a96cab57582f482b8c2" + "resolved_fact_key": "ledger_aggregate_fact_v2_db16ef55b3b0f60d292b745b" }, { - "name": "hmrc/state_pension_income_band_1_000_000_to_inf", + "name": "hmrc/self_employment_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 20000000.0, + "resolved_value": 11000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_9a20bd62d4d5984865242929" + "resolved_fact_key": "ledger_aggregate_fact_v2_315a063dab8497ed5b8837b6" }, { - "name": "hmrc/state_pension_income_band_12_570_to_15_000", + "name": "hmrc/self_employment_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11800000000.0, + "resolved_value": 444000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_45083c1383ea711226aebd1b" + "resolved_fact_key": "ledger_aggregate_fact_v2_498ad10a35b58ff55819bc8b" }, { - "name": "hmrc/state_pension_income_band_15_000_to_20_000", + "name": "hmrc/self_employment_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 22200000000.0, + "resolved_value": 651000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_310febb949c686fad2b71a94" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb849a98f57c60bd507d621b" }, { - "name": "hmrc/state_pension_income_band_150_000_to_200_000", + "name": "hmrc/self_employment_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 265000000.0, + "resolved_value": 40000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_e79668076aadc063559585e9" + "resolved_fact_key": "ledger_aggregate_fact_v2_cfb6ca3c4eff6a83bd5c10ac" }, { - "name": "hmrc/state_pension_income_band_20_000_to_30_000", + "name": "hmrc/self_employment_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 24900000000.0, + "resolved_value": 961000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d18e138c32f6581d6dafdd7" + "resolved_fact_key": "ledger_aggregate_fact_v2_72bd71f362434b2260a4b407" }, { - "name": "hmrc/state_pension_income_band_200_000_to_300_000", + "name": "hmrc/self_employment_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 179000000.0, + "resolved_value": 34000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_e1dda799099ac0f4f439700d" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe86d957cb9590b3292e1757" }, { - "name": "hmrc/state_pension_income_band_30_000_to_40_000", + "name": "hmrc/self_employment_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12300000000.0, + "resolved_value": 595000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_151045b793ac454ab29260fc" + "resolved_fact_key": "ledger_aggregate_fact_v2_84b75f0a77e11de0182b9d87" }, { - "name": "hmrc/state_pension_income_band_300_000_to_500_000", + "name": "hmrc/self_employment_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 96000000.0, + "resolved_value": 21000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c95154893499181b7f3a8903" + "resolved_fact_key": "ledger_aggregate_fact_v2_5c668fd92047d28d73d7c36d" }, { - "name": "hmrc/state_pension_income_band_40_000_to_50_000", + "name": "hmrc/self_employment_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6020000000.0, + "resolved_value": 359000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_bc4cee7d39f5e1c311464a55" + "resolved_fact_key": "ledger_aggregate_fact_v2_876b5e55461ed15a7456d8b3" }, { - "name": "hmrc/state_pension_income_band_50_000_to_70_000", + "name": "hmrc/self_employment_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4660000000.0, + "resolved_value": 311000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7f09c940c0fbc3cc42b9e510" + "resolved_fact_key": "ledger_aggregate_fact_v2_09e5a5c61ccf990f6104a903" }, { - "name": "hmrc/state_pension_income_band_500_000_to_1_000_000", + "name": "hmrc/self_employment_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 43000000.0, + "resolved_value": 15000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d265dfcd4ba09d10053a78a4" + "resolved_fact_key": "ledger_aggregate_fact_v2_73031eb82b28c872e4371fae" }, { - "name": "hmrc/state_pension_income_band_70_000_to_100_000", + "name": "hmrc/self_employment_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1890000000.0, + "resolved_value": 143000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_41c1df25454fdf413d5765d7" + "resolved_fact_key": "ledger_aggregate_fact_v2_c35c3f72e5f7901457970c8d" } ] }, - "hmrc.spi.state_pension.count_by_total_income_band": { + "hmrc.spi.dividend_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/state_pension_count_income_band_100_000_to_150_000", + "name": "hmrc/dividend_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 74000.0, + "resolved_value": 6870000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_01b8f391c006c09d3ed51865" + "resolved_fact_key": "ledger_aggregate_fact_v2_6fd01f132dc6b218c02326b1" }, { - "name": "hmrc/state_pension_count_income_band_1_000_000_to_inf", + "name": "hmrc/dividend_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2000.0, + "resolved_value": 11100000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8c359bb976d919bedb9076a" + "resolved_fact_key": "ledger_aggregate_fact_v2_3c0cd54a0f0609d8ebc58a25" }, { - "name": "hmrc/state_pension_count_income_band_12_570_to_15_000", + "name": "hmrc/dividend_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1140000.0, + "resolved_value": 175000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_05f2cd00648c7f8225723a9c" + "resolved_fact_key": "ledger_aggregate_fact_v2_b63a84056f85bed14b8ab8fd" }, { - "name": "hmrc/state_pension_count_income_band_15_000_to_20_000", + "name": "hmrc/dividend_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2050000.0, + "resolved_value": 855000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ced75bd10fbfa56ef2eabeae" + "resolved_fact_key": "ledger_aggregate_fact_v2_3c4f22fc63944665033b18b3" }, { - "name": "hmrc/state_pension_count_income_band_150_000_to_200_000", + "name": "hmrc/dividend_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 21000.0, + "resolved_value": 3450000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73d438db1a168d794e290b0e" + "resolved_fact_key": "ledger_aggregate_fact_v2_ced1a5840ced099b471d4e84" }, { - "name": "hmrc/state_pension_count_income_band_20_000_to_30_000", + "name": "hmrc/dividend_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2320000.0, + "resolved_value": 3330000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_69b521bf537da156d2afa48e" + "resolved_fact_key": "ledger_aggregate_fact_v2_8a115e840b38a6603d618bc0" }, { - "name": "hmrc/state_pension_count_income_band_200_000_to_300_000", + "name": "hmrc/dividend_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 14000.0, + "resolved_value": 3700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3edcf70605856bb8b906ea19" + "resolved_fact_key": "ledger_aggregate_fact_v2_0394e55216df7f3dcab84fb5" }, { - "name": "hmrc/state_pension_count_income_band_30_000_to_40_000", + "name": "hmrc/dividend_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1160000.0, + "resolved_value": 4700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1cafb0f484a7d8191b7fb989" + "resolved_fact_key": "ledger_aggregate_fact_v2_ea93d59adaf66ef73e9dddbf" }, { - "name": "hmrc/state_pension_count_income_band_300_000_to_500_000", + "name": "hmrc/dividend_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8000.0, + "resolved_value": 3430000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7f510c873457703c57c16983" + "resolved_fact_key": "ledger_aggregate_fact_v2_8d09d2287cbdb2e4f4004521" }, { - "name": "hmrc/state_pension_count_income_band_40_000_to_50_000", + "name": "hmrc/dividend_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 568000.0, + "resolved_value": 8400000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d4ff6839b2d936396ae33f67" + "resolved_fact_key": "ledger_aggregate_fact_v2_0a4329a3eb027a530c6f02ec" }, { - "name": "hmrc/state_pension_count_income_band_50_000_to_70_000", + "name": "hmrc/dividend_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 441000.0, + "resolved_value": 12500000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2b5023baae0b6814c07afbe9" + "resolved_fact_key": "ledger_aggregate_fact_v2_c11497ffe45250b909593f1d" }, { - "name": "hmrc/state_pension_count_income_band_500_000_to_1_000_000", + "name": "hmrc/dividend_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3000.0, + "resolved_value": 3820000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9a834c26fa7c215c052f4f5" + "resolved_fact_key": "ledger_aggregate_fact_v2_dafc8ca1cd03e5d461b11d4e" }, { - "name": "hmrc/state_pension_count_income_band_70_000_to_100_000", + "name": "hmrc/dividend_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 176000.0, + "resolved_value": 9440000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7514fbdbf5f909008b617d06" - } - ] - }, - "hmrc.cgt.taxpayers_total": { - "status": "active", - "candidates": [ - { - "name": "hmrc.cgt.taxpayers_total", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 551000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_31d709fc393c2bf4d04efca5" - } - ] - }, - "hmrc.cgt.gains_total": { - "status": "active", - "candidates": [ - { - "name": "hmrc.cgt.gains_total", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 119258000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_12060d20a417d85d67cf24e8" + "resolved_fact_key": "ledger_aggregate_fact_v2_940e6ce9db10080ed5613faa" } ] }, - "dwp.benefit_cap.capped_households": { + "hmrc.spi.dividend_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households", + "name": "hmrc/dividend_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 110637.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_b698397897ed849f096cdd94" - } - ] - }, - "dwp.pip.daily_living_standard_claimants": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "dwp.pip.daily_living_standard_claimants", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "dwp.pip.daily_living_enhanced_claimants": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "dwp.pip.daily_living_enhanced_claimants", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "dwp.esa_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 222000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_35b535ef60b7e9e8ddad45af" + }, { - "name": "dwp.esa_claimants", + "name": "hmrc/dividend_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1000000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_16ef67af9274891abd5e4fdc" - } - ] - }, - "dwp.esa_contrib_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 19000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_fbe097b0ffbcc0e7a301478d" + }, { - "name": "dwp.esa_contrib_claimants", + "name": "hmrc/dividend_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 620000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_bf22883b03cf631864b2ae1d" - } - ] - }, - "dwp.esa_income_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 115000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3a657db84b033007853ec14b" + }, { - "name": "dwp.esa_income_claimants", + "name": "hmrc/dividend_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 180000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_8684f0c35a1d71a291e61c81" - } - ] - }, - "dwp.jsa_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 372000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_418541677821ff087753a7b4" + }, { - "name": "dwp.jsa_claimants", + "name": "hmrc/dividend_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 71000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_b5d92ff094ad2c534847291a" - } - ] - }, - "dwp.uc.households_children_1": { - "status": "active", - "candidates": [ + "resolved_value": 92000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_426db10645b611899a770dbd" + }, { - "name": "dwp.uc.households_children_1", + "name": "hmrc/dividend_income_count_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1190123.8333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c1533879baf52aaa88758083" - } - ] - }, - "dwp.uc.households_children_2": { - "status": "active", - "candidates": [ + "resolved_value": 843000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_937f405149e37c0c900a62ee" + }, { - "name": "dwp.uc.households_children_2", + "name": "hmrc/dividend_income_count_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1049895.5, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_46fca4f9d4e0519f0c190824" - } - ] - }, - "dwp.uc.households_children_3": { - "status": "active", - "candidates": [ + "resolved_value": 75000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_6c0e32c82b968ba545457cab" + }, { - "name": "dwp.uc.households_children_3", + "name": "hmrc/dividend_income_count_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 477887.6666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba5bce203605d4e16037d311" - } - ] - }, - "dwp.uc.households_children_4": { - "status": "active", - "candidates": [ + "resolved_value": 667000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_c8fc2a8e3993c51b68cc6f8a" + }, { - "name": "dwp.uc.households_children_4", + "name": "hmrc/dividend_income_count_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 170713.66666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_33541aafa05a63dcae4fc144" - } - ] - }, - "dwp.uc.households_children_5_or_more": { - "status": "active", - "candidates": [ + "resolved_value": 49000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_439d9908bf6880e33103ea7d" + }, { - "name": "dwp.uc.households_children_5_or_more", + "name": "hmrc/dividend_income_count_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 76320.08333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_33d99593d166153ca2d0adec" - } - ] - }, - "dwp.uc.households_single_no_children": { - "status": "active", - "candidates": [ + "resolved_value": 627000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_60bb54980a6ca69ff77d07f0" + }, { - "name": "dwp.uc.households_single_no_children", + "name": "hmrc/dividend_income_count_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2990070.1666666665, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c013630f1154eb7252466457" - } - ] - }, - "dwp.uc.households_single_with_children": { - "status": "active", - "candidates": [ + "resolved_value": 643000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_56b8b1dd7aec08c3abddc3a0" + }, { - "name": "dwp.uc.households_single_with_children", + "name": "hmrc/dividend_income_count_income_band_500_000_to_1_000_000", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2138780.1666666665, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4e21ff5e364647d7c75589d2" - } - ] - }, - "dwp.uc.households_couple_no_children": { - "status": "active", - "candidates": [ + "resolved_value": 32000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_c9f024b8595617fc8dd8e416" + }, { - "name": "dwp.uc.households_couple_no_children", + "name": "hmrc/dividend_income_count_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 241130.91666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad46a5483afd6bad20dc50fe" + "resolved_value": 336000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_2ed13533e012fdd1fec68a67" } ] }, - "dwp.uc.households_couple_with_children": { - "status": "active", + "hmrc.spi.property_income.amount_by_total_income_band": { + "status": "signed_excluded", "candidates": [ { - "name": "dwp.uc.households_couple_with_children", - "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, - "resolved_period": 2025, - "resolved_value": 826160.8333333334, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1a76243d3f616b19eaed3e0a" + "name": "hmrc.spi.property_income.amount_by_total_income_band", + "status": "signed_excluded", + "matched_fact_count_overall": 13, + "matched_fact_count_at_or_before_period": 13, + "signed_rationale": "Signed out pending a first-class value-scaling operation or a Chronicle package for HMRC Property Rental Income Statistics with declared reconciliation: the Ledger facts are official HMRC SPI Table 3.7 net property-income amounts, while the incumbent calibration target applies the populace-side x1.9 property-income undercount adjustment. The x1.9 trace is uk-data PR #311 / issue uk-data#230: SPI covers only taxpayers with liability, and HMRC Property Rental Income Statistics show GBP 46.68bn versus SPI about GBP 24.5bn for 2020-21. Binding the raw SPI facts would knowingly calibrate to 10/19 of the incumbent surface." } ] }, - "dwp.uc.payment_distribution_single": { + "hmrc.spi.property_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_0_to_1_200", + "name": "hmrc/property_income_count_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 89479.33333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ab0a2ad4fff5a73eb430af0" + "resolved_value": 137000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_50e02eb85969a4773af5cade" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_1_200_to_2_400", + "name": "hmrc/property_income_count_income_band_1_000_000_to_inf", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 7000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d286366fea43c9f897936709" + }, + { + "name": "hmrc/property_income_count_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 127403.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4da96f3f87204e3b63a7197e" + "resolved_value": 101000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_80d817cee2f3592809f3a194" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_12_000_to_13_200", + "name": "hmrc/property_income_count_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 122035.55555555556, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_100f173ee4233f5ed3616bbc" + "resolved_value": 232000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_2c0d78b9f9dff4e5fdfa250c" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_13_200_to_14_400", + "name": "hmrc/property_income_count_income_band_150_000_to_200_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 197163.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_263205affbfb94c0a87b7834" + "resolved_value": 54000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_5ec672db73bb4f35958a409e" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_14_400_to_15_600", + "name": "hmrc/property_income_count_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 209497.33333333334, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f4e51bd6399c4a72f10e625f" + "resolved_value": 431000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3eb40c70c3de0d0c29253566" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_15_600_to_16_800", + "name": "hmrc/property_income_count_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 149963.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_746aa1e8d116c4543251b137" + "resolved_value": 41000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_0394669c5734865fda5f0541" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_16_800_to_18_000", + "name": "hmrc/property_income_count_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 108689.66666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0dc82a9ba1ce7a8ea1855991" + "resolved_value": 364000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_6564bb4b662365729676a9e1" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_18_000_to_19_200", + "name": "hmrc/property_income_count_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 61718.666666666664, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4399ab26a944d2d46a12311d" + "resolved_value": 23000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_87c457b7ee2392ee8360893b" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_19_200_to_20_400", + "name": "hmrc/property_income_count_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 34050.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8ab0a63fbef46e02aa34d37" + "resolved_value": 325000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7187a98d8342886b08e3f9e2" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_20_400_to_21_600", + "name": "hmrc/property_income_count_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 22338.333333333332, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d22d996cd3edb838030ab0dc" + "resolved_value": 397000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_c44a33c3bc4454de20132027" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_21_600_to_22_800", + "name": "hmrc/property_income_count_income_band_500_000_to_1_000_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 14685.777777777777, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_404ce9f1ea3e17ec602a1de9" + "resolved_value": 13000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_831e0c70ca80d37c785d4122" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_22_800_to_24_000", + "name": "hmrc/property_income_count_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11133.666666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d2268373d3e5894e10f3f004" - }, + "resolved_value": 226000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_f93d04a399cee892e5ec86b6" + } + ] + }, + "hmrc.spi.private_pension_income.amount_by_total_income_band": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600", + "name": "hmrc/private_pension_income_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 197136.66666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_37e9e071fb187dab220f3876" + "resolved_value": 5430000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_cb943439ee9edfb445bc3fa5" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_24_000_to_25_200", + "name": "hmrc/private_pension_income_income_band_1_000_000_to_inf", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6951.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8af773c191130cd03d9de884" + "resolved_value": 370000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7dcf8568040de10d9b3765da" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_25_200_to_26_400", + "name": "hmrc/private_pension_income_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6508.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f46b09c321cf98f8e0d12b89" + "resolved_value": 4350000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_699889c2fb48479e27e44a4a" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_26_400_to_27_600", + "name": "hmrc/private_pension_income_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5913.444444444444, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a763ca2d87febd61de26d8b0" + "resolved_value": 13600000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_0f977d0b50c1d0f1d1364e88" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_27_600_to_28_800", + "name": "hmrc/private_pension_income_income_band_150_000_to_200_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1884.111111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8b6d8894debcbda5e38c0923" + "resolved_value": 1810000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d29aac0680380c80bd842bae" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_28_800_to_30_000", + "name": "hmrc/private_pension_income_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1653.7777777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_aa3077a36f37ae73562e57fc" + "resolved_value": 30200000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_bafcebe21a05cb0ca19d5e4f" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_3_600_to_4_800", + "name": "hmrc/private_pension_income_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 377063.1111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_988e854b9584a36b1b62810f" + "resolved_value": 1570000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_de0ed091681463c4ddec5b85" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_4_800_to_6_000", + "name": "hmrc/private_pension_income_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 195983.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7a3e7c9563c15ba28ffd3c3e" + "resolved_value": 24900000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_2884a006a8d7c144a8570a7d" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_6_000_to_7_200", + "name": "hmrc/private_pension_income_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 114033.33333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_294fdb23cc02a98334267137" + "resolved_value": 1120000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_73e8de3b1ac198cc75c2b696" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_7_200_to_8_400", + "name": "hmrc/private_pension_income_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 149043.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_5d4a92d292c96a2f440dee5a" + "resolved_value": 16900000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_6b29cd5a1d665a00bb3e8046" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_8_400_to_9_600", + "name": "hmrc/private_pension_income_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 399750.22222222225, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad92f85c0ac85ea7bb6e8ca3" + "resolved_value": 17400000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_8f911d955de4f80e87dc69d8" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_9_600_to_10_800", + "name": "hmrc/private_pension_income_income_band_500_000_to_1_000_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 386411.6666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e2bbf1fe386cfcd8db712026" + "resolved_value": 640000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_a13e6165bec82537c5c2883c" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_10_800_to_12_000", + "name": "hmrc/private_pension_income_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 104891.11111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_de2719af6e4d5f9ffe65aaee" + "resolved_value": 9470000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_0a1db235b87cad00eeddbfd8" } ] }, - "dwp.uc.payment_distribution_lone_parent": { + "hmrc.spi.private_pension_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_0_to_1_200", + "name": "hmrc/private_pension_income_count_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 26670.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7b17c88cf49645b2d3ef44a6" + "resolved_value": 109000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1fa1ba97628c6c2c315f0e15" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_1_200_to_2_400", + "name": "hmrc/private_pension_income_count_income_band_1_000_000_to_inf", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 36208.11111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_765ace417ceafd524ffda4c0" + "resolved_value": 2000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_188f8f1a0535263e4db7c9a8" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_12_000_to_13_200", + "name": "hmrc/private_pension_income_count_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 125798.44444444444, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_eaddee052a3861f259b93272" + "resolved_value": 1070000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_853f104082cf479b98952c1a" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_13_200_to_14_400", + "name": "hmrc/private_pension_income_count_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 129133.66666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8d66013c8a68e423f507be8" + "resolved_value": 2140000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_c785199ee1d08fabfe927ff0" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_14_400_to_15_600", + "name": "hmrc/private_pension_income_count_income_band_150_000_to_200_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 115856.66666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1bc84efe74c485d143caab7b" + "resolved_value": 29000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_a98ec830dee0eceb16b452e7" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_15_600_to_16_800", + "name": "hmrc/private_pension_income_count_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 125660.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e26d2d7e425a94fd9fde3d17" + "resolved_value": 2660000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1df6f17a33011c1c026dbc09" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_16_800_to_18_000", + "name": "hmrc/private_pension_income_count_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 135836.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8fa2e062c33297530d458054" + "resolved_value": 20000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_042ab8896eb0214e7bbad477" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_18_000_to_19_200", + "name": "hmrc/private_pension_income_count_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 135444.88888888888, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_77cb72042ffb9b2b1af769e3" + "resolved_value": 1450000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_0a28fd76533fc93cf8dbfe4a" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_19_200_to_20_400", + "name": "hmrc/private_pension_income_count_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 106341.88888888889, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_acb89a96425fd7af119e0c3b" + "resolved_value": 10000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7fccfc3ee4246841b3ed391b" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_20_400_to_21_600", + "name": "hmrc/private_pension_income_count_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 85490.44444444444, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3aa5825f5e5e8dbc570c0af1" + "resolved_value": 779000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_0f808aa135a13e5aa4668d22" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_21_600_to_22_800", + "name": "hmrc/private_pension_income_count_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 80226.88888888889, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c5a0ee450c3ad7f882dfb167" + "resolved_value": 643000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_097efdacf2adf0f90f90d1de" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_22_800_to_24_000", + "name": "hmrc/private_pension_income_count_income_band_500_000_to_1_000_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 71259.55555555556, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_13ffca0d11c038fc7d096ec9" + "resolved_value": 4000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_8abdd0aa368c3d693e6d0989" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_2_400_to_3_600", + "name": "hmrc/private_pension_income_count_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 46312.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6619e26753d01d76247e1759" - }, + "resolved_value": 259000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_f75fc4c3e2cb06bbdb7543f8" + } + ] + }, + "hmrc.spi.state_pension.amount_by_total_income_band": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_24_000_to_25_200", + "name": "hmrc/state_pension_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 51301.666666666664, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4a935006e5c346bfe0009055" + "resolved_value": 847000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d63e1a96cab57582f482b8c2" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_25_200_to_26_400", + "name": "hmrc/state_pension_income_band_1_000_000_to_inf", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 43305.22222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e64560bd9c14d083cd03c985" + "resolved_value": 20000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_9a20bd62d4d5984865242929" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_26_400_to_27_600", + "name": "hmrc/state_pension_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 34910.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8e16d0c97924701eb074c25d" + "resolved_value": 11800000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_45083c1383ea711226aebd1b" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_27_600_to_28_800", + "name": "hmrc/state_pension_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 28513.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf9757018b0d313f20342b59" + "resolved_value": 22200000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_310febb949c686fad2b71a94" + }, + { + "name": "hmrc/state_pension_income_band_150_000_to_200_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 265000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_e79668076aadc063559585e9" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_28_800_to_30_000", + "name": "hmrc/state_pension_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 22593.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6bede883f015e48e86c0a2de" + "resolved_value": 24900000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3d18e138c32f6581d6dafdd7" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_3_600_to_4_800", + "name": "hmrc/state_pension_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 60310.11111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b0710535c8b6006db118eb3b" + "resolved_value": 179000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_e1dda799099ac0f4f439700d" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_4_800_to_6_000", + "name": "hmrc/state_pension_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 67858.66666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b4008c8b22190b4ee185d4f6" + "resolved_value": 12300000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_151045b793ac454ab29260fc" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_6_000_to_7_200", + "name": "hmrc/state_pension_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 89577.44444444444, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d1fadffae053bf60d7fcd7e" + "resolved_value": 96000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_c95154893499181b7f3a8903" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_7_200_to_8_400", + "name": "hmrc/state_pension_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 116076.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fae65610a14d6c22f475d757" + "resolved_value": 6020000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_bc4cee7d39f5e1c311464a55" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_8_400_to_9_600", + "name": "hmrc/state_pension_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 97511.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_540c0869e23edc4a402166bf" + "resolved_value": 4660000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7f09c940c0fbc3cc42b9e510" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_9_600_to_10_800", + "name": "hmrc/state_pension_income_band_500_000_to_1_000_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 102343.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a170bf444a17ae88a80766b0" + "resolved_value": 43000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d265dfcd4ba09d10053a78a4" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_10_800_to_12_000", + "name": "hmrc/state_pension_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 123718.11111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b7d0d6add859217e797a66ea" + "resolved_value": 1890000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_41c1df25454fdf413d5765d7" } ] }, - "dwp.uc.payment_distribution_couple_no_children": { + "hmrc.spi.state_pension.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_0_to_1_200", + "name": "hmrc/state_pension_count_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7506.333333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8af6f4ef9d70ded4a4bf6b5" + "resolved_value": 74000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_01b8f391c006c09d3ed51865" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_1_200_to_2_400", + "name": "hmrc/state_pension_count_income_band_1_000_000_to_inf", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8797.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_28514ff922f7b00a4706e74b" + "resolved_value": 2000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_b8c359bb976d919bedb9076a" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_12_000_to_13_200", + "name": "hmrc/state_pension_count_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16121.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8b8e20276b7af9f670009f64" + "resolved_value": 1140000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_05f2cd00648c7f8225723a9c" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_13_200_to_14_400", + "name": "hmrc/state_pension_count_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13317.333333333334, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_22e83b92481a8b2267a15309" + "resolved_value": 2050000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_ced75bd10fbfa56ef2eabeae" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_14_400_to_15_600", + "name": "hmrc/state_pension_count_income_band_150_000_to_200_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 19657.333333333332, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_42f1cbfe9fee5eb33f69088d" + "resolved_value": 21000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_73d438db1a168d794e290b0e" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_15_600_to_16_800", + "name": "hmrc/state_pension_count_income_band_20_000_to_30_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16443.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_aed9bf66bdbc046ee991fcf5" + "resolved_value": 2320000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_69b521bf537da156d2afa48e" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_16_800_to_18_000", + "name": "hmrc/state_pension_count_income_band_200_000_to_300_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13441.111111111111, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7ccb1420b8ca3e26048291b9" + "resolved_value": 14000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3edcf70605856bb8b906ea19" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_18_000_to_19_200", + "name": "hmrc/state_pension_count_income_band_30_000_to_40_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 10728.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a7057ddde3cd2ffaed246687" + "resolved_value": 1160000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1cafb0f484a7d8191b7fb989" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_19_200_to_20_400", + "name": "hmrc/state_pension_count_income_band_300_000_to_500_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9653.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3e228ab480713f15af6e847c" + "resolved_value": 8000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7f510c873457703c57c16983" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_20_400_to_21_600", + "name": "hmrc/state_pension_count_income_band_40_000_to_50_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6486.888888888889, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ecfd0dfe25ebc098ade1e902" + "resolved_value": 568000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d4ff6839b2d936396ae33f67" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_21_600_to_22_800", + "name": "hmrc/state_pension_count_income_band_50_000_to_70_000", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3981.8888888888887, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2bbf9ab64d9fde9025452375" + "resolved_value": 441000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_2b5023baae0b6814c07afbe9" + }, + { + "name": "hmrc/state_pension_count_income_band_500_000_to_1_000_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 3000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9a834c26fa7c215c052f4f5" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_22_800_to_24_000", + "name": "hmrc/state_pension_count_income_band_70_000_to_100_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 176000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7514fbdbf5f909008b617d06" + } + ] + }, + "hmrc.cgt.taxpayers_total": { + "status": "active", + "candidates": [ + { + "name": "hmrc.cgt.taxpayers_total", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2761.4444444444443, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f19a927835e2aa12a94f6279" - }, + "resolved_value": 551000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_31d709fc393c2bf4d04efca5" + } + ] + }, + "hmrc.cgt.gains_total": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_2_400_to_3_600", + "name": "hmrc.cgt.gains_total", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12256.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_46ba331006269a96f7aee844" - }, + "resolved_value": 119258000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_12060d20a417d85d67cf24e8" + } + ] + }, + "dwp.benefit_cap.capped_households": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_24_000_to_25_200", + "name": "dwp.benefit_cap.capped_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2131.222222222222, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd2ddbef54fc0ec48f61d7b0" - }, + "resolved_value": 110637.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_b698397897ed849f096cdd94" + } + ] + }, + "dwp.pip.daily_living_standard_claimants": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_25_200_to_26_400", + "name": "dwp.pip.daily_living_standard_claimants", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "dwp.pip.daily_living_enhanced_claimants": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "dwp.pip.daily_living_enhanced_claimants", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "dwp.esa_claimants": { + "status": "active", + "candidates": [ + { + "name": "dwp.esa_claimants", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1475.3333333333333, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3ea2b4312343be8d41a37265" - }, + "resolved_value": 1000000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_16ef67af9274891abd5e4fdc" + } + ] + }, + "dwp.esa_contrib_claimants": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_26_400_to_27_600", + "name": "dwp.esa_contrib_claimants", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1073.7777777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_55cf1a8742443b096e81b33e" - }, + "resolved_value": 620000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_bf22883b03cf631864b2ae1d" + } + ] + }, + "dwp.esa_income_claimants": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_27_600_to_28_800", + "name": "dwp.esa_income_claimants", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 746.3333333333334, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6cd7a2f97a5e43ba25481719" - }, + "resolved_value": 180000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_8684f0c35a1d71a291e61c81" + } + ] + }, + "dwp.jsa_claimants": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_28_800_to_30_000", + "name": "dwp.jsa_claimants", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 605.7777777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3f50c2d6d58a3a45681f0c5d" - }, + "resolved_value": 71000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_b5d92ff094ad2c534847291a" + } + ] + }, + "dwp.uc.households_children_1": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_3_600_to_4_800", + "name": "dwp.uc.households_children_1", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 10945.444444444445, + "resolved_value": 1190123.8333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0ead4e96f4e609a16cf1e53e" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_c1533879baf52aaa88758083" + } + ] + }, + "dwp.uc.households_children_2": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_4_800_to_6_000", + "name": "dwp.uc.households_children_2", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 12492.444444444445, + "resolved_value": 1049895.5, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6823b2987ba44d1b85428d2b" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_46fca4f9d4e0519f0c190824" + } + ] + }, + "dwp.uc.households_children_3": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_6_000_to_7_200", + "name": "dwp.uc.households_children_3", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 12979.666666666666, + "resolved_value": 477887.6666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3a3fc258bd18da8c60177380" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ba5bce203605d4e16037d311" + } + ] + }, + "dwp.uc.households_children_4": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_7_200_to_8_400", + "name": "dwp.uc.households_children_4", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 16484.444444444445, + "resolved_value": 170713.66666666666, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b75ef335d484f8dd9ae13a70" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_33541aafa05a63dcae4fc144" + } + ] + }, + "dwp.uc.households_children_5_or_more": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_8_400_to_9_600", + "name": "dwp.uc.households_children_5_or_more", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 15272.444444444445, + "resolved_value": 76320.08333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcd000da1af753b61c9ac5df" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_33d99593d166153ca2d0adec" + } + ] + }, + "dwp.uc.households_single_no_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_9_600_to_10_800", - "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "name": "dwp.uc.households_single_no_children", + "status": "active", + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 19142.333333333332, + "resolved_value": 2990070.1666666665, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d38fa50aa9bf0e85549ec9a" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_c013630f1154eb7252466457" + } + ] + }, + "dwp.uc.households_single_with_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_10_800_to_12_000", + "name": "dwp.uc.households_single_with_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 13313.333333333334, + "resolved_value": 2138780.1666666665, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6697a9dc6c88a1a0b0472a1e" + "resolved_fact_key": "ledger_aggregate_fact_v2_4e21ff5e364647d7c75589d2" } ] }, - "dwp.uc.payment_distribution_couple_with_children": { + "dwp.uc.households_couple_no_children": { "status": "active", "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200", + "name": "dwp.uc.households_couple_no_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 19073.555555555555, + "resolved_value": 241130.91666666666, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8c1548028e499fa8399d1246" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ad46a5483afd6bad20dc50fe" + } + ] + }, + "dwp.uc.households_couple_with_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400", + "name": "dwp.uc.households_couple_with_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 22775.777777777777, + "resolved_value": 826160.8333333334, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff2fef9bd96e583203e111d6" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_1a76243d3f616b19eaed3e0a" + } + ] + }, + "dwp.uc.payment_distribution_single": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_12_000_to_13_200", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_0_to_1_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 40009.555555555555, + "resolved_value": 89479.33333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fee1fd2227a87871edfe2bfa" + "resolved_fact_key": "ledger_aggregate_fact_v2_2ab0a2ad4fff5a73eb430af0" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_13_200_to_14_400", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_1_200_to_2_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 39972.555555555555, + "resolved_value": 127403.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b0427c86dc3df13761ab5b0" + "resolved_fact_key": "ledger_aggregate_fact_v2_4da96f3f87204e3b63a7197e" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_14_400_to_15_600", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_12_000_to_13_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 40518.77777777778, + "resolved_value": 122035.55555555556, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_bfd9a57597b46f356ef9cfc9" + "resolved_fact_key": "ledger_aggregate_fact_v2_100f173ee4233f5ed3616bbc" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_15_600_to_16_800", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_13_200_to_14_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37118.0, + "resolved_value": 197163.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_328ed88b561971d4ee47d852" + "resolved_fact_key": "ledger_aggregate_fact_v2_263205affbfb94c0a87b7834" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_16_800_to_18_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_14_400_to_15_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37177.77777777778, + "resolved_value": 209497.33333333334, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c50c761ddfaab3cbfba62bfd" + "resolved_fact_key": "ledger_aggregate_fact_v2_f4e51bd6399c4a72f10e625f" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_18_000_to_19_200", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_15_600_to_16_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37164.555555555555, + "resolved_value": 149963.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_74d32efc9f1984f60cbd9397" + "resolved_fact_key": "ledger_aggregate_fact_v2_746aa1e8d116c4543251b137" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_19_200_to_20_400", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_16_800_to_18_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 33309.555555555555, + "resolved_value": 108689.66666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_90b7e15c6554b1c74e7055f3" + "resolved_fact_key": "ledger_aggregate_fact_v2_0dc82a9ba1ce7a8ea1855991" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_20_400_to_21_600", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_18_000_to_19_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 29102.555555555555, + "resolved_value": 61718.666666666664, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f9b06f2d2afb65af9a224a" + "resolved_fact_key": "ledger_aggregate_fact_v2_4399ab26a944d2d46a12311d" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_21_600_to_22_800", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_19_200_to_20_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 27534.666666666668, + "resolved_value": 34050.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e65a50de282324e8c188863a" + "resolved_fact_key": "ledger_aggregate_fact_v2_b8ab0a63fbef46e02aa34d37" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_22_800_to_24_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_20_400_to_21_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 25584.777777777777, + "resolved_value": 22338.333333333332, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_16f48d435925ffa44f4d6871" + "resolved_fact_key": "ledger_aggregate_fact_v2_d22d996cd3edb838030ab0dc" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_21_600_to_22_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 26502.666666666668, + "resolved_value": 14685.777777777777, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_93fd0534df01d1dade53397e" + "resolved_fact_key": "ledger_aggregate_fact_v2_404ce9f1ea3e17ec602a1de9" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_24_000_to_25_200", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_22_800_to_24_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 22927.777777777777, + "resolved_value": 11133.666666666666, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffb787487a36c86f94d25a25" + "resolved_fact_key": "ledger_aggregate_fact_v2_d2268373d3e5894e10f3f004" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_25_200_to_26_400", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 20334.666666666668, + "resolved_value": 197136.66666666666, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2f4d504be6f184b7834f2687" + "resolved_fact_key": "ledger_aggregate_fact_v2_37e9e071fb187dab220f3876" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_26_400_to_27_600", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_24_000_to_25_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 17535.0, + "resolved_value": 6951.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_719022eef2836c069c4b02d0" + "resolved_fact_key": "ledger_aggregate_fact_v2_8af773c191130cd03d9de884" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_27_600_to_28_800", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_25_200_to_26_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 15399.888888888889, + "resolved_value": 6508.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b1d8f6516b32e39ecad3873" + "resolved_fact_key": "ledger_aggregate_fact_v2_f46b09c321cf98f8e0d12b89" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_28_800_to_30_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_26_400_to_27_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 12836.222222222223, + "resolved_value": 5913.444444444444, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_115a9ea1e35d76db13756149" + "resolved_fact_key": "ledger_aggregate_fact_v2_a763ca2d87febd61de26d8b0" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_3_600_to_4_800", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_27_600_to_28_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 29027.0, + "resolved_value": 1884.111111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_255e8c862df5351282c29809" + "resolved_fact_key": "ledger_aggregate_fact_v2_8b6d8894debcbda5e38c0923" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_4_800_to_6_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_28_800_to_30_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 32427.0, + "resolved_value": 1653.7777777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_32261034f242507c0a7337b3" + "resolved_fact_key": "ledger_aggregate_fact_v2_aa3077a36f37ae73562e57fc" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_6_000_to_7_200", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_3_600_to_4_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 34956.88888888889, + "resolved_value": 377063.1111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6f40664df124c4dca50524b8" + "resolved_fact_key": "ledger_aggregate_fact_v2_988e854b9584a36b1b62810f" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_7_200_to_8_400", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_4_800_to_6_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37410.77777777778, + "resolved_value": 195983.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_27b091b1a00bc33ab68139f8" + "resolved_fact_key": "ledger_aggregate_fact_v2_7a3e7c9563c15ba28ffd3c3e" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_8_400_to_9_600", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_6_000_to_7_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 39910.333333333336, + "resolved_value": 114033.33333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_22b16b470c0b51499fb2f042" + "resolved_fact_key": "ledger_aggregate_fact_v2_294fdb23cc02a98334267137" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_9_600_to_10_800", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_7_200_to_8_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 39368.0, + "resolved_value": 149043.77777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7dbca9e2f8508f1066399b73" + "resolved_fact_key": "ledger_aggregate_fact_v2_5d4a92d292c96a2f440dee5a" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_10_800_to_12_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_8_400_to_9_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 40805.444444444445, + "resolved_value": 399750.22222222225, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_23cf62e7e58211e783c52d2e" - } - ] - }, - "dwp.uc.scotland_households_child_under_1": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ad92f85c0ac85ea7bb6e8ca3" + }, { - "name": "dwp.uc.scotland_households_child_under_1", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_9_600_to_10_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 14333.222222222223, + "resolved_value": 386411.6666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e88b27e010e08ac8d36d0d30" - } - ] - }, - "dwp.uc.two_child_limit.households_affected": { - "status": "active", - "candidates": [ - { - "name": "dwp.uc.two_child_limit.households_affected", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 469780.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_860a48172c62298ceb00c20b" - } - ] - }, - "dwp.uc.two_child_limit.children_affected": { - "status": "active", - "candidates": [ - { - "name": "dwp.uc.two_child_limit.children_affected", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 597920.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_4378e45ac129e036b4a6ca03" - } - ] - }, - "dwp.uc.two_child_limit.children_in_affected_households": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e2bbf1fe386cfcd8db712026" + }, { - "name": "dwp.uc.two_child_limit.children_in_affected_households", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_10_800_to_12_000", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1665540.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_05774e34488c474df7f84742" + "resolved_value": 104891.11111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_de2719af6e4d5f9ffe65aaee" } ] }, - "dwp.uc.two_child_limit.households_3_children": { + "dwp.uc.payment_distribution_lone_parent": { "status": "active", "candidates": [ { - "name": "dwp.uc.two_child_limit.households_3_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_0_to_1_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 297310.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_dca7734c17910c213e397741" - } - ] - }, - "dwp.uc.two_child_limit.children_in_3_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 26670.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7b17c88cf49645b2d3ef44a6" + }, { - "name": "dwp.uc.two_child_limit.children_in_3_children_households", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_1_200_to_2_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 891930.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_515b2aeb394a9a9a1fd2d195" - } - ] - }, - "dwp.uc.two_child_limit.households_4_children": { - "status": "active", - "candidates": [ + "resolved_value": 36208.11111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_765ace417ceafd524ffda4c0" + }, { - "name": "dwp.uc.two_child_limit.households_4_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_12_000_to_13_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 117190.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_a78a141d4018bdd92678b497" - } - ] - }, - "dwp.uc.two_child_limit.children_in_4_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 125798.44444444444, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_eaddee052a3861f259b93272" + }, { - "name": "dwp.uc.two_child_limit.children_in_4_children_households", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_13_200_to_14_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 468760.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_adef094060710c5b354e7ac4" - } - ] - }, - "dwp.uc.two_child_limit.households_5_children": { - "status": "active", - "candidates": [ + "resolved_value": 129133.66666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b8d66013c8a68e423f507be8" + }, { - "name": "dwp.uc.two_child_limit.households_5_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_14_400_to_15_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37020.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_2c9cfcd7cc862c9c1dd57e4d" - } - ] - }, - "dwp.uc.two_child_limit.children_in_5_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 115856.66666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_1bc84efe74c485d143caab7b" + }, { - "name": "dwp.uc.two_child_limit.children_in_5_children_households", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_15_600_to_16_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 185120.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_2134e60314c98faf54df2498" - } - ] - }, - "dwp.uc.two_child_limit.households_6_plus_children": { - "status": "active", - "candidates": [ + "resolved_value": 125660.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e26d2d7e425a94fd9fde3d17" + }, { - "name": "dwp.uc.two_child_limit.households_6_plus_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_16_800_to_18_000", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 18260.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_e6302f9f933c14e97fc2fcae" - } - ] - }, - "dwp.uc.two_child_limit.children_in_6_plus_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 135836.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8fa2e062c33297530d458054" + }, { - "name": "dwp.uc.two_child_limit.children_in_6_plus_children_households", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_18_000_to_19_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 119720.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_235cb4e779dd669dad2cd421" - } - ] - }, - "dwp.uc.two_child_limit.households_claimant_pip": { - "status": "active", - "candidates": [ + "resolved_value": 135444.88888888888, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_77cb72042ffb9b2b1af769e3" + }, { - "name": "dwp.uc.two_child_limit.households_claimant_pip", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_19_200_to_20_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 65280.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_55dd86462d71be247206b5a2" - } - ] - }, - "dwp.uc.two_child_limit.children_claimant_pip": { - "status": "active", - "candidates": [ + "resolved_value": 106341.88888888889, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_acb89a96425fd7af119e0c3b" + }, { - "name": "dwp.uc.two_child_limit.children_claimant_pip", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_20_400_to_21_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 235270.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe554fcdcb22a77d71c01537" - } - ] - }, - "dwp.uc.two_child_limit.households_disabled_child_element": { - "status": "active", - "candidates": [ + "resolved_value": 85490.44444444444, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3aa5825f5e5e8dbc570c0af1" + }, { - "name": "dwp.uc.two_child_limit.households_disabled_child_element", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_21_600_to_22_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 129630.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_535ef3b4afd474ea14d16d27" - } - ] - }, - "dwp.uc.two_child_limit.children_disabled_child_element": { - "status": "active", - "candidates": [ + "resolved_value": 80226.88888888889, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_c5a0ee450c3ad7f882dfb167" + }, + { + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_22_800_to_24_000", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 71259.55555555556, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_13ffca0d11c038fc7d096ec9" + }, + { + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_2_400_to_3_600", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 46312.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6619e26753d01d76247e1759" + }, + { + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_24_000_to_25_200", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 51301.666666666664, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_4a935006e5c346bfe0009055" + }, + { + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_25_200_to_26_400", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 43305.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e64560bd9c14d083cd03c985" + }, { - "name": "dwp.uc.two_child_limit.children_disabled_child_element", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_26_400_to_27_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 479460.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_ac642b7002518167b56e1537" - } - ] - }, - "ons.population.uk_total": { - "status": "active", - "candidates": [ + "resolved_value": 34910.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8e16d0c97924701eb074c25d" + }, { - "name": "ons.population.uk_total", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_27_600_to_28_800", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 69281437.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6c212695ea75be0d2a635e9b" - } - ] - }, - "ons.population.age_0_9_by_region": { - "status": "active", - "candidates": [ + "resolved_value": 28513.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_cf9757018b0d313f20342b59" + }, { - "name": "ons.population.age_0_9_by_region@E12000001", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_28_800_to_30_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 285165.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c796672d4d88aa11ab15a31a" + "resolved_value": 22593.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6bede883f015e48e86c0a2de" }, { - "name": "ons.population.age_0_9_by_region@E12000002", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_3_600_to_4_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 865892.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de0fc360f660f7a387628062" + "resolved_value": 60310.11111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b0710535c8b6006db118eb3b" }, { - "name": "ons.population.age_0_9_by_region@E12000003", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_4_800_to_6_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 626938.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cbc8ee6d7552af4ba61edcb1" + "resolved_value": 67858.66666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b4008c8b22190b4ee185d4f6" }, { - "name": "ons.population.age_0_9_by_region@E12000004", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_6_000_to_7_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 543004.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f858f629484e7989a9dc1f0b" + "resolved_value": 89577.44444444444, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_1d1fadffae053bf60d7fcd7e" }, { - "name": "ons.population.age_0_9_by_region@E12000005", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_7_200_to_8_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 718837.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de2d9b45547f640fbc7ebb5a" + "resolved_value": 116076.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_fae65610a14d6c22f475d757" }, { - "name": "ons.population.age_0_9_by_region@E12000006", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_8_400_to_9_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 744698.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fec32a4b3417958969f5f2d9" + "resolved_value": 97511.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_540c0869e23edc4a402166bf" }, { - "name": "ons.population.age_0_9_by_region@E12000007", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_9_600_to_10_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1054493.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cdd134faa924b905bd8a36ad" + "resolved_value": 102343.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_a170bf444a17ae88a80766b0" }, { - "name": "ons.population.age_0_9_by_region@E12000008", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_10_800_to_12_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1059434.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0ef951a6bad79d44726fe11" + "resolved_value": 123718.11111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b7d0d6add859217e797a66ea" + } + ] + }, + "dwp.uc.payment_distribution_couple_no_children": { + "status": "active", + "candidates": [ + { + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_0_to_1_200", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 7506.333333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e8af6f4ef9d70ded4a4bf6b5" }, { - "name": "ons.population.age_0_9_by_region@E12000009", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_1_200_to_2_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 575506.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d6a250010241c987a217b54f" + "resolved_value": 8797.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_28514ff922f7b00a4706e74b" }, { - "name": "ons.population.age_0_9_by_region@W92000004", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_12_000_to_13_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 321552.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eef268031d128fde4eec5d91" + "resolved_value": 16121.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8b8e20276b7af9f670009f64" }, { - "name": "ons.population.age_0_9_by_region@S92000003", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_13_200_to_14_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 527989.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" + "resolved_value": 13317.333333333334, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_22e83b92481a8b2267a15309" }, { - "name": "ons.population.age_0_9_by_region@N92000002", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_14_400_to_15_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 229505.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb8519582dac5a21a72f8360" - } - ] - }, - "ons.population.age_10_19_by_region": { - "status": "active", - "candidates": [ + "resolved_value": 19657.333333333332, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_42f1cbfe9fee5eb33f69088d" + }, { - "name": "ons.population.age_10_19_by_region@E12000001", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_15_600_to_16_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 326306.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ce36092d33f50f712f620485" + "resolved_value": 16443.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_aed9bf66bdbc046ee991fcf5" }, { - "name": "ons.population.age_10_19_by_region@E12000002", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_16_800_to_18_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 952864.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6fc45432de26717dc50151d" + "resolved_value": 13441.111111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7ccb1420b8ca3e26048291b9" }, { - "name": "ons.population.age_10_19_by_region@E12000003", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_18_000_to_19_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 696780.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1942c03893e2aeccb514e34" + "resolved_value": 10728.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_a7057ddde3cd2ffaed246687" }, { - "name": "ons.population.age_10_19_by_region@E12000004", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_19_200_to_20_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 615630.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d96b0e1445c879a8267ef553" + "resolved_value": 9653.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3e228ab480713f15af6e847c" }, { - "name": "ons.population.age_10_19_by_region@E12000005", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_20_400_to_21_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 785062.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff921d8727a6c1ea11548896" + "resolved_value": 6486.888888888889, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ecfd0dfe25ebc098ade1e902" }, { - "name": "ons.population.age_10_19_by_region@E12000006", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_21_600_to_22_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 785091.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d66fd1b48bc1e9ae4d38f778" + "resolved_value": 3981.8888888888887, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_2bbf9ab64d9fde9025452375" }, { - "name": "ons.population.age_10_19_by_region@E12000007", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_22_800_to_24_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1068691.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8b79fef8b80acc1deb297b7" + "resolved_value": 2761.4444444444443, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f19a927835e2aa12a94f6279" }, { - "name": "ons.population.age_10_19_by_region@E12000008", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_2_400_to_3_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1183235.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba4c8f8e6cb789626f191523" + "resolved_value": 12256.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_46ba331006269a96f7aee844" }, { - "name": "ons.population.age_10_19_by_region@E12000009", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_24_000_to_25_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 677228.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8ea04bba18d65ed2ac0dd74" + "resolved_value": 2131.222222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_dd2ddbef54fc0ec48f61d7b0" }, { - "name": "ons.population.age_10_19_by_region@W92000004", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_25_200_to_26_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 374851.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f040814c3de37f315671a60d" + "resolved_value": 1475.3333333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3ea2b4312343be8d41a37265" }, { - "name": "ons.population.age_10_19_by_region@S92000003", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_26_400_to_27_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 612935.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d8cb95f3b8a4eb5725ec1e0d" + "resolved_value": 1073.7777777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_55cf1a8742443b096e81b33e" }, { - "name": "ons.population.age_10_19_by_region@N92000002", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_27_600_to_28_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 252764.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef301c6ab42b35eb692e20b0" - } - ] - }, - "ons.population.age_20_29_by_region": { - "status": "active", - "candidates": [ + "resolved_value": 746.3333333333334, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6cd7a2f97a5e43ba25481719" + }, { - "name": "ons.population.age_20_29_by_region@E12000001", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_28_800_to_30_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 343015.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ebe0b2ced4987cd701db581a" + "resolved_value": 605.7777777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3f50c2d6d58a3a45681f0c5d" }, { - "name": "ons.population.age_20_29_by_region@E12000002", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_3_600_to_4_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 986590.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe94b1572d6db93b57407bcd" + "resolved_value": 10945.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_0ead4e96f4e609a16cf1e53e" }, { - "name": "ons.population.age_20_29_by_region@E12000003", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_4_800_to_6_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 717479.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cb721748c503839a9229a404" + "resolved_value": 12492.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6823b2987ba44d1b85428d2b" }, { - "name": "ons.population.age_20_29_by_region@E12000004", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_6_000_to_7_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 612108.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7be7895d4f680a502caeb4b" + "resolved_value": 12979.666666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3a3fc258bd18da8c60177380" }, { - "name": "ons.population.age_20_29_by_region@E12000005", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_7_200_to_8_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 766058.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f539e665a5478f92346bb4d4" + "resolved_value": 16484.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b75ef335d484f8dd9ae13a70" }, { - "name": "ons.population.age_20_29_by_region@E12000006", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_8_400_to_9_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 727218.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff31c89cfa957bdd279c9947" + "resolved_value": 15272.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_fcd000da1af753b61c9ac5df" }, { - "name": "ons.population.age_20_29_by_region@E12000007", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_9_600_to_10_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1508607.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0ffc4e5795625b9238d6dde" + "resolved_value": 19142.333333333332, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3d38fa50aa9bf0e85549ec9a" }, { - "name": "ons.population.age_20_29_by_region@E12000008", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_10_800_to_12_000", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 13313.333333333334, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6697a9dc6c88a1a0b0472a1e" + } + ] + }, + "dwp.uc.payment_distribution_couple_with_children": { + "status": "active", + "candidates": [ + { + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1066121.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f3a720e9d1d4664e83307a9a" + "resolved_value": 19073.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8c1548028e499fa8399d1246" }, { - "name": "ons.population.age_20_29_by_region@E12000009", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 684393.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe520978b4f4105aa292a3f5" + "resolved_value": 22775.777777777777, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff2fef9bd96e583203e111d6" }, { - "name": "ons.population.age_20_29_by_region@W92000004", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_12_000_to_13_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 380557.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe44434fdb2e33179826ee35" + "resolved_value": 40009.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_fee1fd2227a87871edfe2bfa" }, { - "name": "ons.population.age_20_29_by_region@S92000003", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_13_200_to_14_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 703554.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dadba40aea2eb5dcdb2e5d6e" + "resolved_value": 39972.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3b0427c86dc3df13761ab5b0" }, { - "name": "ons.population.age_20_29_by_region@N92000002", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_14_400_to_15_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 219525.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_afe826389a344a01c4be2862" - } - ] - }, - "ons.population.age_30_39_by_region": { - "status": "active", - "candidates": [ + "resolved_value": 40518.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_bfd9a57597b46f356ef9cfc9" + }, { - "name": "ons.population.age_30_39_by_region@E12000001", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_15_600_to_16_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 363357.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ceb94ab430de1f0bc8c19ce4" + "resolved_value": 37118.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_328ed88b561971d4ee47d852" }, { - "name": "ons.population.age_30_39_by_region@E12000002", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_16_800_to_18_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1064968.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eeb6e6194f0405a4b7010913" + "resolved_value": 37177.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_c50c761ddfaab3cbfba62bfd" }, { - "name": "ons.population.age_30_39_by_region@E12000003", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_18_000_to_19_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 770809.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ebc2a149da9287a3a2b28d45" + "resolved_value": 37164.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_74d32efc9f1984f60cbd9397" }, { - "name": "ons.population.age_30_39_by_region@E12000004", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_19_200_to_20_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 676709.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fefffb16e9e1a25fd0da3435" + "resolved_value": 33309.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_90b7e15c6554b1c74e7055f3" }, { - "name": "ons.population.age_30_39_by_region@E12000005", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_20_400_to_21_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 839114.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eaee3d4e99154692dbad24b9" + "resolved_value": 29102.555555555555, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_96f9b06f2d2afb65af9a224a" }, { - "name": "ons.population.age_30_39_by_region@E12000006", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_21_600_to_22_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 895639.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbb89267af1b9a1a349f3274" + "resolved_value": 27534.666666666668, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e65a50de282324e8c188863a" }, { - "name": "ons.population.age_30_39_by_region@E12000007", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_22_800_to_24_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1537372.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c7d5874566b099143ddbac28" + "resolved_value": 25584.777777777777, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_16f48d435925ffa44f4d6871" }, { - "name": "ons.population.age_30_39_by_region@E12000008", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1284552.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4aa5baed49b53887253b70" + "resolved_value": 26502.666666666668, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_93fd0534df01d1dade53397e" }, { - "name": "ons.population.age_30_39_by_region@E12000009", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_24_000_to_25_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 742082.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8c6ce01a5aa83ce392ccf3a" + "resolved_value": 22927.777777777777, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffb787487a36c86f94d25a25" }, { - "name": "ons.population.age_30_39_by_region@W92000004", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_25_200_to_26_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 410248.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa74c4da871af17e8af431d6" + "resolved_value": 20334.666666666668, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_2f4d504be6f184b7834f2687" }, { - "name": "ons.population.age_30_39_by_region@S92000003", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_26_400_to_27_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 733480.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f045b554aebb8f1b21df5a5c" + "resolved_value": 17535.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_719022eef2836c069c4b02d0" }, { - "name": "ons.population.age_30_39_by_region@N92000002", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_27_600_to_28_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 254067.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb383d007487ef1df14f4946" - } - ] - }, - "ons.population.age_40_49_by_region": { - "status": "active", - "candidates": [ + "resolved_value": 15399.888888888889, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_3b1d8f6516b32e39ecad3873" + }, { - "name": "ons.population.age_40_49_by_region@E12000001", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_28_800_to_30_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 320860.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f081bcb6c2e794e8ec3b0161" + "resolved_value": 12836.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_115a9ea1e35d76db13756149" }, { - "name": "ons.population.age_40_49_by_region@E12000002", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_3_600_to_4_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 930967.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7744877e123c00b96511818" + "resolved_value": 29027.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_255e8c862df5351282c29809" }, { - "name": "ons.population.age_40_49_by_region@E12000003", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_4_800_to_6_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 674349.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d6e708c298712163b552e6c7" + "resolved_value": 32427.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_32261034f242507c0a7337b3" }, { - "name": "ons.population.age_40_49_by_region@E12000004", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_6_000_to_7_200", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 610611.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e861cd162b6b06a1107ca177" + "resolved_value": 34956.88888888889, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_6f40664df124c4dca50524b8" }, { - "name": "ons.population.age_40_49_by_region@E12000005", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_7_200_to_8_400", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 746341.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa28a64a0b8ec87502b44a9f" + "resolved_value": 37410.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_27b091b1a00bc33ab68139f8" }, { - "name": "ons.population.age_40_49_by_region@E12000006", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_8_400_to_9_600", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 838578.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f94400c214a5c3c3847cc562" + "resolved_value": 39910.333333333336, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_22b16b470c0b51499fb2f042" }, { - "name": "ons.population.age_40_49_by_region@E12000007", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_9_600_to_10_800", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1268973.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb8228a78efb8cdb3dd46764" + "resolved_value": 39368.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7dbca9e2f8508f1066399b73" }, { - "name": "ons.population.age_40_49_by_region@E12000008", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_10_800_to_12_000", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1255951.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edac715ea904f29dbd3332f9" - }, + "resolved_value": 40805.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_23cf62e7e58211e783c52d2e" + } + ] + }, + "dwp.uc.scotland_households_child_under_1": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_40_49_by_region@E12000009", + "name": "dwp.uc.scotland_households_child_under_1", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 688417.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6ecf5ebd09a5d638cf6dd15" - }, + "resolved_value": 14333.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e88b27e010e08ac8d36d0d30" + } + ] + }, + "dwp.uc.two_child_limit.households_affected": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_40_49_by_region@W92000004", + "name": "dwp.uc.two_child_limit.households_affected", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 365951.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6496b4ebd88792d288206a1" - }, + "resolved_value": 469780.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_860a48172c62298ceb00c20b" + } + ] + }, + "dwp.uc.two_child_limit.children_affected": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_40_49_by_region@S92000003", + "name": "dwp.uc.two_child_limit.children_affected", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 675368.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e159eb5144ceae58dccb4dc0" - }, + "resolved_value": 597920.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_4378e45ac129e036b4a6ca03" + } + ] + }, + "dwp.uc.two_child_limit.children_in_affected_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_40_49_by_region@N92000002", + "name": "dwp.uc.two_child_limit.children_in_affected_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 246140.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b71979cb27997e512ea68888" + "resolved_value": 1665540.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_05774e34488c474df7f84742" } ] }, - "ons.population.age_50_59_by_region": { + "dwp.uc.two_child_limit.households_3_children": { "status": "active", "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000001", + "name": "dwp.uc.two_child_limit.households_3_children", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 360074.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8febade5d1aa4eff5515f79" - }, + "resolved_value": 297310.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_dca7734c17910c213e397741" + } + ] + }, + "dwp.uc.two_child_limit.children_in_3_children_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000002", + "name": "dwp.uc.two_child_limit.children_in_3_children_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 995810.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ce316c567d2d3919bad74247" - }, + "resolved_value": 891930.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_515b2aeb394a9a9a1fd2d195" + } + ] + }, + "dwp.uc.two_child_limit.households_4_children": { + "status": "active", + "candidates": [ + { + "name": "dwp.uc.two_child_limit.households_4_children", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 117190.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_a78a141d4018bdd92678b497" + } + ] + }, + "dwp.uc.two_child_limit.children_in_4_children_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000003", + "name": "dwp.uc.two_child_limit.children_in_4_children_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 736903.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f07e470e70895701083be7b4" - }, + "resolved_value": 468760.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_adef094060710c5b354e7ac4" + } + ] + }, + "dwp.uc.two_child_limit.households_5_children": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000004", + "name": "dwp.uc.two_child_limit.households_5_children", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 676307.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc3b848c0d546908542f7522" - }, + "resolved_value": 37020.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_2c9cfcd7cc862c9c1dd57e4d" + } + ] + }, + "dwp.uc.two_child_limit.children_in_5_children_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000005", + "name": "dwp.uc.two_child_limit.children_in_5_children_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 794143.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eced9fed4ca113ee655134b7" - }, + "resolved_value": 185120.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_2134e60314c98faf54df2498" + } + ] + }, + "dwp.uc.two_child_limit.households_6_plus_children": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000006", + "name": "dwp.uc.two_child_limit.households_6_plus_children", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 866946.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8011436193a375ac63a33af" - }, + "resolved_value": 18260.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_e6302f9f933c14e97fc2fcae" + } + ] + }, + "dwp.uc.two_child_limit.children_in_6_plus_children_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000007", + "name": "dwp.uc.two_child_limit.children_in_6_plus_children_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1087518.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c0999183e74a6f6978377427" - }, + "resolved_value": 119720.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_235cb4e779dd669dad2cd421" + } + ] + }, + "dwp.uc.two_child_limit.households_claimant_pip": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000008", + "name": "dwp.uc.two_child_limit.households_claimant_pip", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1287719.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5b6740db34f7f702bb230fb" - }, + "resolved_value": 65280.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_55dd86462d71be247206b5a2" + } + ] + }, + "dwp.uc.two_child_limit.children_claimant_pip": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000009", + "name": "dwp.uc.two_child_limit.children_claimant_pip", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 784718.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf32f90895454cdb82d3a611" - }, + "resolved_value": 235270.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe554fcdcb22a77d71c01537" + } + ] + }, + "dwp.uc.two_child_limit.households_disabled_child_element": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@W92000004", + "name": "dwp.uc.two_child_limit.households_disabled_child_element", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 424694.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ed905faab304a40013587ffd" - }, + "resolved_value": 129630.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_535ef3b4afd474ea14d16d27" + } + ] + }, + "dwp.uc.two_child_limit.children_disabled_child_element": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@S92000003", + "name": "dwp.uc.two_child_limit.children_disabled_child_element", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 766715.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f332e28940d1c94b1e2dec31" - }, + "resolved_value": 479460.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_ac642b7002518167b56e1537" + } + ] + }, + "ons.population.uk_total": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_50_59_by_region@N92000002", + "name": "ons.population.uk_total", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 255269.0, + "resolved_value": 69281437.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f786aada1891e9f309902c1c" + "resolved_fact_key": "ledger_aggregate_fact_v2_6c212695ea75be0d2a635e9b" } ] }, - "ons.population.age_60_69_by_region": { + "ons.population.age_0_9_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000001", + "name": "ons.population.age_0_9_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 349719.0, + "resolved_value": 285165.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4466f1cb6fb29ce9b132b0" + "resolved_fact_key": "ledger_aggregate_fact_v2_c796672d4d88aa11ab15a31a" }, { - "name": "ons.population.age_60_69_by_region@E12000002", + "name": "ons.population.age_0_9_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 884043.0, + "resolved_value": 865892.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f861d328dbb8a01929eb1e91" + "resolved_fact_key": "ledger_aggregate_fact_v2_de0fc360f660f7a387628062" }, { - "name": "ons.population.age_60_69_by_region@E12000003", + "name": "ons.population.age_0_9_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 652931.0, + "resolved_value": 626938.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9ab6846d67db88fda81fa30" + "resolved_fact_key": "ledger_aggregate_fact_v2_cbc8ee6d7552af4ba61edcb1" }, { - "name": "ons.population.age_60_69_by_region@E12000004", + "name": "ons.population.age_0_9_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 591429.0, + "resolved_value": 543004.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e884ef403c95938c7ebf961b" + "resolved_fact_key": "ledger_aggregate_fact_v2_f858f629484e7989a9dc1f0b" }, { - "name": "ons.population.age_60_69_by_region@E12000005", + "name": "ons.population.age_0_9_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 677922.0, + "resolved_value": 718837.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd4d62d07376896553d9fb66" + "resolved_fact_key": "ledger_aggregate_fact_v2_de2d9b45547f640fbc7ebb5a" }, { - "name": "ons.population.age_60_69_by_region@E12000006", + "name": "ons.population.age_0_9_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 744651.0, + "resolved_value": 744698.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f77f96051d8340645148d138" + "resolved_fact_key": "ledger_aggregate_fact_v2_fec32a4b3417958969f5f2d9" }, { - "name": "ons.population.age_60_69_by_region@E12000007", + "name": "ons.population.age_0_9_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 787666.0, + "resolved_value": 1054493.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e9f63f0939b77a41ec815de0" + "resolved_fact_key": "ledger_aggregate_fact_v2_cdd134faa924b905bd8a36ad" }, { - "name": "ons.population.age_60_69_by_region@E12000008", + "name": "ons.population.age_0_9_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1089421.0, + "resolved_value": 1059434.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8667b0358441f18c2f8e548" + "resolved_fact_key": "ledger_aggregate_fact_v2_f0ef951a6bad79d44726fe11" }, { - "name": "ons.population.age_60_69_by_region@E12000009", + "name": "ons.population.age_0_9_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 736639.0, + "resolved_value": 575506.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f923cb193de625676c40b5c4" + "resolved_fact_key": "ledger_aggregate_fact_v2_d6a250010241c987a217b54f" }, { - "name": "ons.population.age_60_69_by_region@W92000004", + "name": "ons.population.age_0_9_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 401775.0, + "resolved_value": 321552.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f518ad65099be8a424a62142" + "resolved_fact_key": "ledger_aggregate_fact_v2_eef268031d128fde4eec5d91" }, { - "name": "ons.population.age_60_69_by_region@S92000003", + "name": "ons.population.age_0_9_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 721727.0, + "resolved_value": 527989.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e893656e104d3c1c375fa5e7" + "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" }, { - "name": "ons.population.age_60_69_by_region@N92000002", + "name": "ons.population.age_0_9_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 223111.0, + "resolved_value": 229505.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f6e8f32b460fefc304aeee" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb8519582dac5a21a72f8360" } ] }, - "ons.population.age_70_79_by_region": { + "ons.population.age_10_19_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000001", + "name": "ons.population.age_10_19_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 265573.0, + "resolved_value": 326306.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f135bc83bf0e2495ccab922b" + "resolved_fact_key": "ledger_aggregate_fact_v2_ce36092d33f50f712f620485" }, { - "name": "ons.population.age_70_79_by_region@E12000002", + "name": "ons.population.age_10_19_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 669277.0, + "resolved_value": 952864.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f18853f5a9046c59334188d3" + "resolved_fact_key": "ledger_aggregate_fact_v2_f6fc45432de26717dc50151d" }, { - "name": "ons.population.age_70_79_by_region@E12000003", + "name": "ons.population.age_10_19_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 504131.0, + "resolved_value": 696780.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f71c0090e322cc6b02a80193" + "resolved_fact_key": "ledger_aggregate_fact_v2_f1942c03893e2aeccb514e34" }, { - "name": "ons.population.age_70_79_by_region@E12000004", + "name": "ons.population.age_10_19_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 466530.0, + "resolved_value": 615630.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1eaa2a27d34d75f4fcaf147" + "resolved_fact_key": "ledger_aggregate_fact_v2_d96b0e1445c879a8267ef553" }, { - "name": "ons.population.age_70_79_by_region@E12000005", + "name": "ons.population.age_10_19_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 528207.0, + "resolved_value": 785062.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6ed607ecc20a6bd1c0c8bef" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff921d8727a6c1ea11548896" }, { - "name": "ons.population.age_70_79_by_region@E12000006", + "name": "ons.population.age_10_19_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 599882.0, + "resolved_value": 785091.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef2c110c9bb5462379338b17" + "resolved_fact_key": "ledger_aggregate_fact_v2_d66fd1b48bc1e9ae4d38f778" }, { - "name": "ons.population.age_70_79_by_region@E12000007", + "name": "ons.population.age_10_19_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 485057.0, + "resolved_value": 1068691.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9b7f415855dd808a1aee77c" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8b79fef8b80acc1deb297b7" }, { - "name": "ons.population.age_70_79_by_region@E12000008", + "name": "ons.population.age_10_19_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 865392.0, + "resolved_value": 1183235.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dea0c6655095781f862cf7ac" + "resolved_fact_key": "ledger_aggregate_fact_v2_ba4c8f8e6cb789626f191523" }, { - "name": "ons.population.age_70_79_by_region@E12000009", + "name": "ons.population.age_10_19_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 618254.0, + "resolved_value": 677228.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8898137aad748593321b2fb" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8ea04bba18d65ed2ac0dd74" }, { - "name": "ons.population.age_70_79_by_region@W92000004", + "name": "ons.population.age_10_19_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 321668.0, + "resolved_value": 374851.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1de159eac6f90c69f7aef22" + "resolved_fact_key": "ledger_aggregate_fact_v2_f040814c3de37f315671a60d" }, { - "name": "ons.population.age_70_79_by_region@S92000003", + "name": "ons.population.age_10_19_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 519252.0, + "resolved_value": 612935.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f506930ca553f609fe076c9c" + "resolved_fact_key": "ledger_aggregate_fact_v2_d8cb95f3b8a4eb5725ec1e0d" }, { - "name": "ons.population.age_70_79_by_region@N92000002", + "name": "ons.population.age_10_19_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 155382.0, + "resolved_value": 252764.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ec559b1c9b44b3acc8de9073" + "resolved_fact_key": "ledger_aggregate_fact_v2_ef301c6ab42b35eb692e20b0" } ] }, - "ons.population.age_80_89_by_region": { + "ons.population.age_20_29_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000001", + "name": "ons.population.age_20_29_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 122118.0, + "resolved_value": 343015.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eec7f31aac48f686e0d9a343" + "resolved_fact_key": "ledger_aggregate_fact_v2_ebe0b2ced4987cd701db581a" }, { - "name": "ons.population.age_80_89_by_region@E12000002", + "name": "ons.population.age_20_29_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 324141.0, + "resolved_value": 986590.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5dcf6bfa6186fc6200bb9cd" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe94b1572d6db93b57407bcd" }, { - "name": "ons.population.age_80_89_by_region@E12000003", + "name": "ons.population.age_20_29_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 243274.0, + "resolved_value": 717479.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ed30948324557f6bd25a0064" + "resolved_fact_key": "ledger_aggregate_fact_v2_cb721748c503839a9229a404" }, { - "name": "ons.population.age_80_89_by_region@E12000004", + "name": "ons.population.age_20_29_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 225626.0, + "resolved_value": 612108.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f32be81803e3b527361467e0" + "resolved_fact_key": "ledger_aggregate_fact_v2_f7be7895d4f680a502caeb4b" }, { - "name": "ons.population.age_80_89_by_region@E12000005", + "name": "ons.population.age_20_29_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 275030.0, + "resolved_value": 766058.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f252d1b20801bc91a40a9a12" + "resolved_fact_key": "ledger_aggregate_fact_v2_f539e665a5478f92346bb4d4" }, { - "name": "ons.population.age_80_89_by_region@E12000006", + "name": "ons.population.age_20_29_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 305691.0, + "resolved_value": 727218.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d387c1edf10113b2b8602fc3" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff31c89cfa957bdd279c9947" }, { - "name": "ons.population.age_80_89_by_region@E12000007", + "name": "ons.population.age_20_29_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 237061.0, + "resolved_value": 1508607.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa7d5971f83d3ece501a33c7" + "resolved_fact_key": "ledger_aggregate_fact_v2_f0ffc4e5795625b9238d6dde" }, { - "name": "ons.population.age_80_89_by_region@E12000008", + "name": "ons.population.age_20_29_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 447958.0, + "resolved_value": 1066121.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bb61f66f5159481b73615674" + "resolved_fact_key": "ledger_aggregate_fact_v2_f3a720e9d1d4664e83307a9a" }, { - "name": "ons.population.age_80_89_by_region@E12000009", + "name": "ons.population.age_20_29_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 313605.0, + "resolved_value": 684393.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ea5f3461bbda1967761f0d48" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe520978b4f4105aa292a3f5" }, { - "name": "ons.population.age_80_89_by_region@W92000004", + "name": "ons.population.age_20_29_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 154319.0, + "resolved_value": 380557.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d766d2003f1fd56635d53589" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe44434fdb2e33179826ee35" }, { - "name": "ons.population.age_80_89_by_region@S92000003", + "name": "ons.population.age_20_29_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 238904.0, + "resolved_value": 703554.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f206015a88100a72b83bbe9f" + "resolved_fact_key": "ledger_aggregate_fact_v2_dadba40aea2eb5dcdb2e5d6e" }, { - "name": "ons.population.age_80_89_by_region@N92000002", + "name": "ons.population.age_20_29_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 77441.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb5795d1ea12a7a7005a9ee9" - } - ] - }, - "ons.population.female_0_4": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_0_4", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 1744355.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb55d5f20f74ee39a1e8fcb4" - } - ] - }, - "ons.population.female_10_14": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_10_14", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 2052052.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9a457edc9491e5810c39f5f" - } - ] - }, - "ons.population.female_15_19": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_15_19", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 2002835.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0e2139b52c615925c9075dd" - } - ] - }, - "ons.population.female_20_24": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_20_24", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 2034609.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b4e36c0dc0a924667be47bbc" - } - ] - }, - "ons.population.female_25_29": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_25_29", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 2291610.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9d6a711d0cbc4919a8643c0" - } - ] - }, - "ons.population.female_30_34": { - "status": "active", - "candidates": [ - { - "name": "ons.population.female_30_34", - "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "resolved_period": 2025, - "resolved_value": 2463301.0, + "resolved_value": 219525.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5b1d6c400b912b05c79c477" + "resolved_fact_key": "ledger_aggregate_fact_v2_afe826389a344a01c4be2862" } ] }, - "ons.population.female_35_39": { + "ons.population.age_30_39_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.female_35_39", + "name": "ons.population.age_30_39_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 2472291.0, + "resolved_value": 363357.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f927cc9b3eab0494caf1479f" - } - ] - }, - "ons.population.female_40_44": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ceb94ab430de1f0bc8c19ce4" + }, { - "name": "ons.population.female_40_44", + "name": "ons.population.age_30_39_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 2333109.0, + "resolved_value": 1064968.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9cdf746ffe5df2fd3d85279" - } - ] - }, - "ons.population.female_45_49": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_eeb6e6194f0405a4b7010913" + }, { - "name": "ons.population.female_45_49", + "name": "ons.population.age_30_39_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2088285.0, + "resolved_value": 770809.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b679e4770750b86af6b1756b" - } - ] - }, - "ons.population.female_50_54": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ebc2a149da9287a3a2b28d45" + }, { - "name": "ons.population.female_50_54", + "name": "ons.population.age_30_39_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2255231.0, + "resolved_value": 676709.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_65b8a4cc92c4565b00007877" - } - ] - }, - "ons.population.female_55_59": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fefffb16e9e1a25fd0da3435" + }, { - "name": "ons.population.female_55_59", + "name": "ons.population.age_30_39_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2360202.0, + "resolved_value": 839114.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba87a7d66cb9f8694b952159" - } - ] - }, - "ons.population.female_5_9": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_eaee3d4e99154692dbad24b9" + }, { - "name": "ons.population.female_5_9", + "name": "ons.population.age_30_39_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 1941658.0, + "resolved_value": 895639.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bca9c38347810a944bbd08b3" - } - ] - }, - "ons.population.female_60_64": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fbb89267af1b9a1a349f3274" + }, { - "name": "ons.population.female_60_64", + "name": "ons.population.age_30_39_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 2193915.0, + "resolved_value": 1537372.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f3b1f78e4b752640465521f0" - } - ] - }, - "ons.population.female_65_69": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_c7d5874566b099143ddbac28" + }, { - "name": "ons.population.female_65_69", + "name": "ons.population.age_30_39_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1838574.0, + "resolved_value": 1284552.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dbeb583b16bcb530ee1296e1" - } - ] - }, - "ons.population.female_70_74": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4aa5baed49b53887253b70" + }, { - "name": "ons.population.female_70_74", + "name": "ons.population.age_30_39_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 1622996.0, + "resolved_value": 742082.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b962c8b6d3d68808831aad6a" - } - ] - }, - "ons.population.female_75_79": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f8c6ce01a5aa83ce392ccf3a" + }, { - "name": "ons.population.female_75_79", + "name": "ons.population.age_30_39_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 1551183.0, + "resolved_value": 410248.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_aa0a8a7ab2d3894db7a7d7aa" - } - ] - }, - "ons.population.female_80_84": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fa74c4da871af17e8af431d6" + }, { - "name": "ons.population.female_80_84", + "name": "ons.population.age_30_39_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 1024480.0, + "resolved_value": 733480.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcdc2e2f119de0b65769ef90" - } - ] - }, - "ons.population.female_85_89": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f045b554aebb8f1b21df5a5c" + }, { - "name": "ons.population.female_85_89", + "name": "ons.population.age_30_39_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 665267.0, + "resolved_value": 254067.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c76df00751abbf64b5ab056b" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb383d007487ef1df14f4946" } ] }, - "ons.population.female_90_plus": { + "ons.population.age_40_49_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.female_90_plus", + "name": "ons.population.age_40_49_by_region@E12000001", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", + "resolved_period": 2025, + "resolved_value": 320860.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f081bcb6c2e794e8ec3b0161" + }, + { + "name": "ons.population.age_40_49_by_region@E12000002", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 930967.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7744877e123c00b96511818" + }, + { + "name": "ons.population.age_40_49_by_region@E12000003", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", + "resolved_period": 2025, + "resolved_value": 674349.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d6e708c298712163b552e6c7" + }, + { + "name": "ons.population.age_40_49_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 414716.0, + "resolved_value": 610611.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_009d5dd487f317483e9d7b3d" - } - ] - }, - "ons.population.male_0_4": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e861cd162b6b06a1107ca177" + }, { - "name": "ons.population.male_0_4", + "name": "ons.population.age_40_49_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 1829801.0, + "resolved_value": 746341.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ccdfe5dde7b46840510e21d2" - } - ] - }, - "ons.population.male_10_14": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fa28a64a0b8ec87502b44a9f" + }, { - "name": "ons.population.male_10_14", + "name": "ons.population.age_40_49_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 2152800.0, + "resolved_value": 838578.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_86d603b352e77fd0c03ddaa8" - } - ] - }, - "ons.population.male_15_19": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f94400c214a5c3c3847cc562" + }, { - "name": "ons.population.male_15_19", + "name": "ons.population.age_40_49_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 2123750.0, + "resolved_value": 1268973.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ecf390d4b25b71d12aae6bc7" - } - ] - }, - "ons.population.male_20_24": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fb8228a78efb8cdb3dd46764" + }, { - "name": "ons.population.male_20_24", + "name": "ons.population.age_40_49_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 2131646.0, + "resolved_value": 1255951.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edb961b3528b22769eece352" - } - ] - }, - "ons.population.male_25_29": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_edac715ea904f29dbd3332f9" + }, { - "name": "ons.population.male_25_29", + "name": "ons.population.age_40_49_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 2257360.0, + "resolved_value": 688417.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd52338de8e1557cdd024c36" - } - ] - }, - "ons.population.male_30_34": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f6ecf5ebd09a5d638cf6dd15" + }, { - "name": "ons.population.male_30_34", + "name": "ons.population.age_40_49_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 2333326.0, + "resolved_value": 365951.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b81f56fab808ad1d38d70f3d" - } - ] - }, - "ons.population.male_35_39": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f6496b4ebd88792d288206a1" + }, { - "name": "ons.population.male_35_39", + "name": "ons.population.age_40_49_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 2303479.0, + "resolved_value": 675368.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_be9bedc792e0d419ebaf5316" - } - ] - }, - "ons.population.male_40_44": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e159eb5144ceae58dccb4dc0" + }, { - "name": "ons.population.male_40_44", + "name": "ons.population.age_40_49_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 2196013.0, + "resolved_value": 246140.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d41ff91bfe885debcc12d759" + "resolved_fact_key": "ledger_aggregate_fact_v2_b71979cb27997e512ea68888" } ] }, - "ons.population.male_45_49": { + "ons.population.age_50_59_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.male_45_49", + "name": "ons.population.age_50_59_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 2005099.0, + "resolved_value": 360074.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fafcbae6e55f9ae20bc0050d" - } - ] - }, - "ons.population.male_50_54": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f8febade5d1aa4eff5515f79" + }, { - "name": "ons.population.male_50_54", + "name": "ons.population.age_50_59_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 2164862.0, + "resolved_value": 995810.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8fe92cfb43b9a95f8a9f7ef" - } - ] - }, - "ons.population.male_55_59": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ce316c567d2d3919bad74247" + }, { - "name": "ons.population.male_55_59", + "name": "ons.population.age_50_59_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2256521.0, + "resolved_value": 736903.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_86b57e4ed1e5186f23dc4021" - } - ] - }, - "ons.population.male_5_9": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f07e470e70895701083be7b4" + }, { - "name": "ons.population.male_5_9", + "name": "ons.population.age_50_59_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2037199.0, + "resolved_value": 676307.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e272f955c58535b8b9304759" - } - ] - }, - "ons.population.male_60_64": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_fc3b848c0d546908542f7522" + }, { - "name": "ons.population.male_60_64", + "name": "ons.population.age_50_59_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2094462.0, + "resolved_value": 794143.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e60d33e33dcbc1ba2292edf5" - } - ] - }, - "ons.population.male_65_69": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_eced9fed4ca113ee655134b7" + }, { - "name": "ons.population.male_65_69", + "name": "ons.population.age_50_59_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 1734083.0, + "resolved_value": 866946.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a4878efd0023575bded6b67a" - } - ] - }, - "ons.population.male_70_74": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f8011436193a375ac63a33af" + }, { - "name": "ons.population.male_70_74", + "name": "ons.population.age_50_59_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1473758.0, + "resolved_value": 1087518.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d34aca91f9d1621ea96e72bc" - } - ] - }, - "ons.population.male_75_79": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_c0999183e74a6f6978377427" + }, { - "name": "ons.population.male_75_79", + "name": "ons.population.age_50_59_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1350668.0, + "resolved_value": 1287719.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f74158203e735d37a67c5409" - } - ] - }, - "ons.population.male_80_84": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f5b6740db34f7f702bb230fb" + }, { - "name": "ons.population.male_80_84", + "name": "ons.population.age_50_59_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 815910.0, + "resolved_value": 784718.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_60aa57af44ada9286df3d649" - } - ] - }, - "ons.population.male_85_89": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_cf32f90895454cdb82d3a611" + }, { - "name": "ons.population.male_85_89", + "name": "ons.population.age_50_59_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 459511.0, + "resolved_value": 424694.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bbfd4e781a7d1151855e4edb" - } - ] - }, - "ons.population.male_90_plus": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ed905faab304a40013587ffd" + }, { - "name": "ons.population.male_90_plus", + "name": "ons.population.age_50_59_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 210520.0, + "resolved_value": 766715.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_8ec6d2d034546c9693c4f6ed" - } - ] - }, - "ons.population.scotland_children_under_16": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_f332e28940d1c94b1e2dec31" + }, { - "name": "ons.population.scotland_children_under_16", + "name": "ons.population.age_50_59_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 32, - "matched_fact_count_at_or_before_period": 32, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 896833.0, + "resolved_value": 255269.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" + "resolved_fact_key": "ledger_aggregate_fact_v2_f786aada1891e9f309902c1c" } ] }, - "ons.population.scotland_babies_under_1": { + "ons.population.age_60_69_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.scotland_babies_under_1", + "name": "ons.population.age_60_69_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 46776.0, + "resolved_value": 349719.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edd043df0081e63ad0876932" - } - ] - }, - "ons.population.scotland_households_3plus_children": { - "status": "signed_excluded", - "candidates": [ - { - "name": "ons.population.scotland_households_3plus_children", - "status": "signed_excluded", - "matched_fact_count_overall": 552, - "matched_fact_count_at_or_before_period": 552, - "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." - } - ] - }, - "ons.household_composition.lone_households_under_65": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4466f1cb6fb29ce9b132b0" + }, { - "name": "ons.household_composition.lone_households_under_65", + "name": "ons.population.age_60_69_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 4316000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b2ee6bff131571b7dcd4c33c" - } - ] - }, - "ons.household_composition.lone_households_over_65": { - "status": "active", - "candidates": [ + "resolved_value": 884043.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f861d328dbb8a01929eb1e91" + }, { - "name": "ons.household_composition.lone_households_over_65", + "name": "ons.population.age_60_69_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 4254000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4178a72ada0e0b5b53fd62b3" - } - ] - }, - "ons.household_composition.unrelated_adult_households": { - "status": "active", - "candidates": [ + "resolved_value": 652931.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9ab6846d67db88fda81fa30" + }, { - "name": "ons.household_composition.unrelated_adult_households", + "name": "ons.population.age_60_69_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 813000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_191e954854307c61fca2d539" - } - ] - }, - "ons.household_composition.couple_no_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 591429.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e884ef403c95938c7ebf961b" + }, { - "name": "ons.household_composition.couple_no_children_households", + "name": "ons.population.age_60_69_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 8119000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_861314257d00193080069624" - } - ] - }, - "ons.household_composition.couple_under_3_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 677922.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd4d62d07376896553d9fb66" + }, { - "name": "ons.household_composition.couple_under_3_children_households", + "name": "ons.population.age_60_69_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 5439000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_04ac3660df720d6f8effbdb2" - } - ] - }, - "ons.household_composition.couple_3_plus_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 744651.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f77f96051d8340645148d138" + }, { - "name": "ons.household_composition.couple_3_plus_children_households", + "name": "ons.population.age_60_69_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 931000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_3432d322cadb6a40f0c3ebc8" - } - ] - }, - "ons.household_composition.couple_non_dependent_children_only_households": { - "status": "active", - "candidates": [ + "resolved_value": 787666.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e9f63f0939b77a41ec815de0" + }, { - "name": "ons.household_composition.couple_non_dependent_children_only_households", + "name": "ons.population.age_60_69_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1848000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4d36f952f4dd650bcab7ba7f" - } - ] - }, - "ons.household_composition.lone_parent_dependent_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 1089421.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8667b0358441f18c2f8e548" + }, { - "name": "ons.household_composition.lone_parent_dependent_children_households", + "name": "ons.population.age_60_69_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 1835000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e9746f29548db6f6047842cb" - } - ] - }, - "ons.household_composition.lone_parent_non_dependent_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 736639.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f923cb193de625676c40b5c4" + }, { - "name": "ons.household_composition.lone_parent_non_dependent_children_households", + "name": "ons.population.age_60_69_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 1204000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_9c7f117f90bc24f073f4e14f" - } - ] - }, - "ons.household_composition.multi_family_households": { - "status": "active", - "candidates": [ + "resolved_value": 401775.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f518ad65099be8a424a62142" + }, { - "name": "ons.household_composition.multi_family_households", + "name": "ons.population.age_60_69_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 244000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_a0cd8874e5334242ce7b8ce0" + "resolved_value": 721727.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e893656e104d3c1c375fa5e7" + }, + { + "name": "ons.population.age_60_69_by_region@N92000002", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", + "resolved_period": 2025, + "resolved_value": 223111.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f6e8f32b460fefc304aeee" } ] }, - "mhclg.council_tax_stock.band_a": { + "ons.population.age_70_79_by_region": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_a@E12000001", + "name": "ons.population.age_70_79_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 621096.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d0152c2791236d6ec749fb4b" + "resolved_value": 265573.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f135bc83bf0e2495ccab922b" }, { - "name": "mhclg.council_tax_stock.band_a@E12000002", + "name": "ons.population.age_70_79_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 1285713.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa7c76228b4383e695be0c57" + "resolved_value": 669277.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f18853f5a9046c59334188d3" }, { - "name": "mhclg.council_tax_stock.band_a@E12000003", + "name": "ons.population.age_70_79_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 988548.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb94428708527c6adbce48c3" + "resolved_value": 504131.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f71c0090e322cc6b02a80193" }, { - "name": "mhclg.council_tax_stock.band_a@E12000004", + "name": "ons.population.age_70_79_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 739971.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f17101c03f5970d639ddb6d7" + "resolved_value": 466530.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f1eaa2a27d34d75f4fcaf147" }, { - "name": "mhclg.council_tax_stock.band_a@E12000005", + "name": "ons.population.age_70_79_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 728493.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef49e263051486267b93c7cd" + "resolved_value": 528207.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f6ed607ecc20a6bd1c0c8bef" }, { - "name": "mhclg.council_tax_stock.band_a@E12000006", + "name": "ons.population.age_70_79_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 364482.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9ada16eb0c916b22d2397bb" + "resolved_value": 599882.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef2c110c9bb5462379338b17" }, { - "name": "mhclg.council_tax_stock.band_a@E12000007", + "name": "ons.population.age_70_79_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 118732.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7d8d56243116fa2f1419fe1" + "resolved_value": 485057.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d9b7f415855dd808a1aee77c" }, { - "name": "mhclg.council_tax_stock.band_a@E12000008", + "name": "ons.population.age_70_79_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 320025.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcc7bbe5d78c199fc6d856ca" + "resolved_value": 865392.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_dea0c6655095781f862cf7ac" + }, + { + "name": "ons.population.age_70_79_by_region@E12000009", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", + "resolved_period": 2025, + "resolved_value": 618254.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e8898137aad748593321b2fb" + }, + { + "name": "ons.population.age_70_79_by_region@W92000004", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", + "resolved_period": 2025, + "resolved_value": 321668.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f1de159eac6f90c69f7aef22" + }, + { + "name": "ons.population.age_70_79_by_region@S92000003", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", + "resolved_period": 2025, + "resolved_value": 519252.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f506930ca553f609fe076c9c" }, { - "name": "mhclg.council_tax_stock.band_a@E12000009", + "name": "ons.population.age_70_79_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 422969.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f23d41b29d6952c18d44dc26" + "resolved_value": 155382.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ec559b1c9b44b3acc8de9073" } ] }, - "mhclg.council_tax_stock.band_b": { + "ons.population.age_80_89_by_region": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_b@E12000001", + "name": "ons.population.age_80_89_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 193309.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f84be54967344adf03fab807" + "resolved_value": 122118.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_eec7f31aac48f686e0d9a343" }, { - "name": "mhclg.council_tax_stock.band_b@E12000002", + "name": "ons.population.age_80_89_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 666970.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fac49fea11fd3b1110a941c5" + "resolved_value": 324141.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f5dcf6bfa6186fc6200bb9cd" }, { - "name": "mhclg.council_tax_stock.band_b@E12000003", + "name": "ons.population.age_80_89_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 482052.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8ef63f3e9b07a934c3f2df8" + "resolved_value": 243274.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ed30948324557f6bd25a0064" }, { - "name": "mhclg.council_tax_stock.band_b@E12000004", + "name": "ons.population.age_80_89_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 478320.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f48dde558979080156b8c99f" + "resolved_value": 225626.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f32be81803e3b527361467e0" }, { - "name": "mhclg.council_tax_stock.band_b@E12000005", + "name": "ons.population.age_80_89_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 625673.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc4a526b4ee56ed620ab4c14" + "resolved_value": 275030.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f252d1b20801bc91a40a9a12" }, { - "name": "mhclg.council_tax_stock.band_b@E12000006", + "name": "ons.population.age_80_89_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 568914.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe310977523bcaadf025f7f6" + "resolved_value": 305691.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d387c1edf10113b2b8602fc3" }, { - "name": "mhclg.council_tax_stock.band_b@E12000007", + "name": "ons.population.age_80_89_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 463447.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffadb386ab954d99278ba891" + "resolved_value": 237061.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa7d5971f83d3ece501a33c7" }, { - "name": "mhclg.council_tax_stock.band_b@E12000008", + "name": "ons.population.age_80_89_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 649092.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb23fbffbee284d17da76489" + "resolved_value": 447958.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_bb61f66f5159481b73615674" }, { - "name": "mhclg.council_tax_stock.band_b@E12000009", + "name": "ons.population.age_80_89_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 609286.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f84a549115340205a9ae8951" + "resolved_value": 313605.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ea5f3461bbda1967761f0d48" + }, + { + "name": "ons.population.age_80_89_by_region@W92000004", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", + "resolved_period": 2025, + "resolved_value": 154319.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d766d2003f1fd56635d53589" + }, + { + "name": "ons.population.age_80_89_by_region@S92000003", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", + "resolved_period": 2025, + "resolved_value": 238904.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f206015a88100a72b83bbe9f" + }, + { + "name": "ons.population.age_80_89_by_region@N92000002", + "status": "active", + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", + "resolved_period": 2025, + "resolved_value": 77441.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb5795d1ea12a7a7005a9ee9" } ] }, - "mhclg.council_tax_stock.band_c": { + "ons.population.female_0_4": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000001", + "name": "ons.population.female_0_4", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 186703.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e5eaf3e7f4def06c8d938e5f" - }, + "resolved_value": 1744355.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb55d5f20f74ee39a1e8fcb4" + } + ] + }, + "ons.population.female_10_14": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000002", + "name": "ons.population.female_10_14", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2052052.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9a457edc9491e5810c39f5f" + } + ] + }, + "ons.population.female_15_19": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_15_19", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2002835.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f0e2139b52c615925c9075dd" + } + ] + }, + "ons.population.female_20_24": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_20_24", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2034609.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b4e36c0dc0a924667be47bbc" + } + ] + }, + "ons.population.female_25_29": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_25_29", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2291610.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d9d6a711d0cbc4919a8643c0" + } + ] + }, + "ons.population.female_30_34": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_30_34", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 585587.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc2f9b5b1813a71f580f85a4" - }, + "resolved_value": 2463301.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f5b1d6c400b912b05c79c477" + } + ] + }, + "ons.population.female_35_39": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000003", + "name": "ons.population.female_35_39", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 408440.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe416e96e8e324e0e1647008" - }, + "resolved_value": 2472291.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f927cc9b3eab0494caf1479f" + } + ] + }, + "ons.population.female_40_44": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000004", + "name": "ons.population.female_40_44", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 384470.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa1e7c770b7403c2a2663980" - }, + "resolved_value": 2333109.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d9cdf746ffe5df2fd3d85279" + } + ] + }, + "ons.population.female_45_49": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000005", + "name": "ons.population.female_45_49", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 503657.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffab2e562cd756fa9f44ac4c" - }, + "resolved_value": 2088285.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b679e4770750b86af6b1756b" + } + ] + }, + "ons.population.female_50_54": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000006", + "name": "ons.population.female_50_54", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 708146.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff565a1885420d902566f5be" - }, + "resolved_value": 2255231.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_65b8a4cc92c4565b00007877" + } + ] + }, + "ons.population.female_55_59": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000007", + "name": "ons.population.female_55_59", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 991205.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb754d4d8153e7497df94fa9" - }, + "resolved_value": 2360202.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ba87a7d66cb9f8694b952159" + } + ] + }, + "ons.population.female_5_9": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000008", + "name": "ons.population.female_5_9", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 1024169.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_feb50a6c4dfa72419ef9e591" - }, + "resolved_value": 1941658.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_bca9c38347810a944bbd08b3" + } + ] + }, + "ons.population.female_60_64": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000009", + "name": "ons.population.female_60_64", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 587214.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fff7d7ced3067ef09f8e6d12" + "resolved_value": 2193915.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f3b1f78e4b752640465521f0" } ] }, - "mhclg.council_tax_stock.band_d": { + "ons.population.female_65_69": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000001", + "name": "ons.population.female_65_69", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 108432.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb2d7a086ad6d3c95a074ab0" - }, + "resolved_value": 1838574.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_dbeb583b16bcb530ee1296e1" + } + ] + }, + "ons.population.female_70_74": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000002", + "name": "ons.population.female_70_74", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 346489.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff0d7ad8c7d5d0d2f02702f0" - }, + "resolved_value": 1622996.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b962c8b6d3d68808831aad6a" + } + ] + }, + "ons.population.female_75_79": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000003", + "name": "ons.population.female_75_79", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 237496.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7c0b8b92776a6109a114a92" - }, + "resolved_value": 1551183.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_aa0a8a7ab2d3894db7a7d7aa" + } + ] + }, + "ons.population.female_80_84": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000004", + "name": "ons.population.female_80_84", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 238335.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa621220d1e5d193343634ca" - }, + "resolved_value": 1024480.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fcdc2e2f119de0b65769ef90" + } + ] + }, + "ons.population.female_85_89": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000005", + "name": "ons.population.female_85_89", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", - "resolved_period": 2025, - "resolved_value": 288790.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff6f72e91c98eb23dfe9d09c" - }, + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 665267.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c76df00751abbf64b5ab056b" + } + ] + }, + "ons.population.female_90_plus": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000006", + "name": "ons.population.female_90_plus", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 485975.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd87126e89fd8a33383640f1" - }, + "resolved_value": 414716.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_009d5dd487f317483e9d7b3d" + } + ] + }, + "ons.population.male_0_4": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000007", + "name": "ons.population.male_0_4", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 929941.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7dfce8ada24dca8651cdc12" - }, + "resolved_value": 1829801.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ccdfe5dde7b46840510e21d2" + } + ] + }, + "ons.population.male_10_14": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000008", + "name": "ons.population.male_10_14", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 807114.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8129a3bae48724ddc91e4ca" - }, + "resolved_value": 2152800.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_86d603b352e77fd0c03ddaa8" + } + ] + }, + "ons.population.male_15_19": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000009", + "name": "ons.population.male_15_19", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 404568.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f3dcc56f346a75bfa16137" + "resolved_value": 2123750.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ecf390d4b25b71d12aae6bc7" } ] }, - "mhclg.council_tax_stock.band_e": { + "ons.population.male_20_24": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000001", + "name": "ons.population.male_20_24", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 58932.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e767a90e1f4f3985379189f5" - }, + "resolved_value": 2131646.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_edb961b3528b22769eece352" + } + ] + }, + "ons.population.male_25_29": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000002", + "name": "ons.population.male_25_29", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 207825.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9b8ef4202908453655767f0" - }, + "resolved_value": 2257360.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd52338de8e1557cdd024c36" + } + ] + }, + "ons.population.male_30_34": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000003", + "name": "ons.population.male_30_34", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 152517.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbb09c3c4f80ba784375aa37" - }, + "resolved_value": 2333326.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b81f56fab808ad1d38d70f3d" + } + ] + }, + "ons.population.male_35_39": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000004", + "name": "ons.population.male_35_39", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 149931.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fec984442b918005ccc92238" - }, + "resolved_value": 2303479.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_be9bedc792e0d419ebaf5316" + } + ] + }, + "ons.population.male_40_44": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000005", + "name": "ons.population.male_40_44", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 185672.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d83f9067bfa886482b6a5be7" - }, + "resolved_value": 2196013.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d41ff91bfe885debcc12d759" + } + ] + }, + "ons.population.male_45_49": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000006", + "name": "ons.population.male_45_49", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 301723.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb2e48afaa19a026d3d2dbf9" - }, + "resolved_value": 2005099.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fafcbae6e55f9ae20bc0050d" + } + ] + }, + "ons.population.male_50_54": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000007", + "name": "ons.population.male_50_54", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 551952.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe53b4ade27bba47669221bb" - }, + "resolved_value": 2164862.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b8fe92cfb43b9a95f8a9f7ef" + } + ] + }, + "ons.population.male_55_59": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000008", + "name": "ons.population.male_55_59", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 529137.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff8b7b878381855ff02392c8" - }, + "resolved_value": 2256521.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_86b57e4ed1e5186f23dc4021" + } + ] + }, + "ons.population.male_5_9": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000009", + "name": "ons.population.male_5_9", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 274120.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd8affa54b589a8f8dfa76e1" + "resolved_value": 2037199.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e272f955c58535b8b9304759" } ] }, - "mhclg.council_tax_stock.band_f": { + "ons.population.male_60_64": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000001", + "name": "ons.population.male_60_64", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 25729.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1a656e56ed4ec922ab1be8a" - }, + "resolved_value": 2094462.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e60d33e33dcbc1ba2292edf5" + } + ] + }, + "ons.population.male_65_69": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000002", + "name": "ons.population.male_65_69", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 100117.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f934ec4447a2decb7d93153c" - }, + "resolved_value": 1734083.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a4878efd0023575bded6b67a" + } + ] + }, + "ons.population.male_70_74": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000003", + "name": "ons.population.male_70_74", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 73172.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fed1e74402841596ec02537f" - }, + "resolved_value": 1473758.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d34aca91f9d1621ea96e72bc" + } + ] + }, + "ons.population.male_75_79": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000004", + "name": "ons.population.male_75_79", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 71418.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f992d8c87d194b0dfb07b0fa" - }, + "resolved_value": 1350668.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f74158203e735d37a67c5409" + } + ] + }, + "ons.population.male_80_84": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000005", + "name": "ons.population.male_80_84", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 102077.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f49f0636d79cb28dcc85e1" - }, + "resolved_value": 815910.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_60aa57af44ada9286df3d649" + } + ] + }, + "ons.population.male_85_89": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000006", + "name": "ons.population.male_85_89", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 166744.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e672d9b03691ddd1faac694d" - }, + "resolved_value": 459511.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_bbfd4e781a7d1151855e4edb" + } + ] + }, + "ons.population.male_90_plus": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000007", + "name": "ons.population.male_90_plus", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 279261.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef478a0ef6ff0cb78a65dcaa" - }, + "resolved_value": 210520.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_8ec6d2d034546c9693c4f6ed" + } + ] + }, + "ons.population.scotland_children_under_16": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000008", + "name": "ons.population.scotland_children_under_16", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 32, + "matched_fact_count_at_or_before_period": 32, "resolved_period": 2025, - "resolved_value": 325815.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb02357269b3d262a700cf5f" - }, + "resolved_value": 896833.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" + } + ] + }, + "ons.population.scotland_babies_under_1": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000009", + "name": "ons.population.scotland_babies_under_1", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 139412.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb77e2f50e126802cff79f21" + "resolved_value": 46776.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_edd043df0081e63ad0876932" } ] }, - "mhclg.council_tax_stock.band_g": { + "ons.population.scotland_households_3plus_children": { + "status": "signed_excluded", + "candidates": [ + { + "name": "ons.population.scotland_households_3plus_children", + "status": "signed_excluded", + "matched_fact_count_overall": 552, + "matched_fact_count_at_or_before_period": 552, + "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." + } + ] + }, + "ons.household_composition.lone_households_under_65": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000001", + "name": "ons.household_composition.lone_households_under_65", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 14062.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f80042add7dbd445217cde1a" - }, + "resolved_value": 4316000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b2ee6bff131571b7dcd4c33c" + } + ] + }, + "ons.household_composition.lone_households_over_65": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000002", + "name": "ons.household_composition.lone_households_over_65", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, + "resolved_period": 2025, + "resolved_value": 4254000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4178a72ada0e0b5b53fd62b3" + } + ] + }, + "ons.household_composition.unrelated_adult_households": { + "status": "active", + "candidates": [ + { + "name": "ons.household_composition.unrelated_adult_households", + "status": "active", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 62587.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffc555374f59e3667468b086" - }, + "resolved_value": 813000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_191e954854307c61fca2d539" + } + ] + }, + "ons.household_composition.couple_no_children_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000003", + "name": "ons.household_composition.couple_no_children_households", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 40487.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f290bf6f13fa468c2acf0be2" - }, + "resolved_value": 8119000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_861314257d00193080069624" + } + ] + }, + "ons.household_composition.couple_under_3_children_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000004", + "name": "ons.household_composition.couple_under_3_children_households", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 37892.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f69d9fecd8d273243af03685" - }, + "resolved_value": 5439000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_04ac3660df720d6f8effbdb2" + } + ] + }, + "ons.household_composition.couple_3_plus_children_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000005", + "name": "ons.household_composition.couple_3_plus_children_households", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 60209.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ec75efe3a83bc6d9c25d7ae1" - }, + "resolved_value": 931000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_3432d322cadb6a40f0c3ebc8" + } + ] + }, + "ons.household_composition.couple_non_dependent_children_only_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000006", + "name": "ons.household_composition.couple_non_dependent_children_only_households", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 108700.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd2a0529ed0a7cf9532ef8ea" - }, + "resolved_value": 1848000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4d36f952f4dd650bcab7ba7f" + } + ] + }, + "ons.household_composition.lone_parent_dependent_children_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000007", + "name": "ons.household_composition.lone_parent_dependent_children_households", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 207056.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7d99e8a41825169a450a9ed" - }, + "resolved_value": 1835000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e9746f29548db6f6047842cb" + } + ] + }, + "ons.household_composition.lone_parent_non_dependent_children_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000008", + "name": "ons.household_composition.lone_parent_non_dependent_children_households", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 255206.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fda73631af17107d741fed93" - }, + "resolved_value": 1204000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_9c7f117f90bc24f073f4e14f" + } + ] + }, + "ons.household_composition.multi_family_households": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000009", + "name": "ons.household_composition.multi_family_households", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 75533.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ddffd3467540ebe8f71dc050" + "resolved_value": 244000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_a0cd8874e5334242ce7b8ce0" } ] }, - "mhclg.council_tax_stock.band_h": { + "mhclg.council_tax_stock.band_a": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000001", + "name": "mhclg.council_tax_stock.band_a@E12000001", "status": "active", "matched_fact_count_overall": 4776, "matched_fact_count_at_or_before_period": 4728, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 1151.0, + "resolved_value": 621096.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4150e637c1d82a68bb2a28" + "resolved_fact_key": "ledger_aggregate_fact_v2_d0152c2791236d6ec749fb4b" }, { - "name": "mhclg.council_tax_stock.band_h@E12000002", + "name": "mhclg.council_tax_stock.band_a@E12000002", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 6230.0, + "resolved_value": 1285713.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f742ed87e05f38e0a20ba028" + "resolved_fact_key": "ledger_aggregate_fact_v2_fa7c76228b4383e695be0c57" }, { - "name": "mhclg.council_tax_stock.band_h@E12000003", + "name": "mhclg.council_tax_stock.band_a@E12000003", "status": "active", "matched_fact_count_overall": 5970, "matched_fact_count_at_or_before_period": 5910, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 3022.0, + "resolved_value": 988548.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd393adec42be55cfefb3400" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb94428708527c6adbce48c3" }, { - "name": "mhclg.council_tax_stock.band_h@E12000004", + "name": "mhclg.council_tax_stock.band_a@E12000004", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2779.0, + "resolved_value": 739971.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe1b32af9c019b0fa366ea83" + "resolved_fact_key": "ledger_aggregate_fact_v2_f17101c03f5970d639ddb6d7" }, { - "name": "mhclg.council_tax_stock.band_h@E12000005", + "name": "mhclg.council_tax_stock.band_a@E12000005", "status": "active", "matched_fact_count_overall": 11940, "matched_fact_count_at_or_before_period": 11820, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 5285.0, + "resolved_value": 728493.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f086bebb12518f66fdd27be8" + "resolved_fact_key": "ledger_aggregate_fact_v2_ef49e263051486267b93c7cd" }, { - "name": "mhclg.council_tax_stock.band_h@E12000006", + "name": "mhclg.council_tax_stock.band_a@E12000006", "status": "active", "matched_fact_count_overall": 17910, "matched_fact_count_at_or_before_period": 17730, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 13447.0, + "resolved_value": 364482.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb031812869aaf579b6d5b62" + "resolved_fact_key": "ledger_aggregate_fact_v2_f9ada16eb0c916b22d2397bb" }, { - "name": "mhclg.council_tax_stock.band_h@E12000007", + "name": "mhclg.council_tax_stock.band_a@E12000007", "status": "active", "matched_fact_count_overall": 13134, "matched_fact_count_at_or_before_period": 13002, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 59569.0, + "resolved_value": 118732.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb5c13d22ffe09151cf3b4f8" + "resolved_fact_key": "ledger_aggregate_fact_v2_f7d8d56243116fa2f1419fe1" }, { - "name": "mhclg.council_tax_stock.band_h@E12000008", + "name": "mhclg.council_tax_stock.band_a@E12000008", "status": "active", "matched_fact_count_overall": 25472, "matched_fact_count_at_or_before_period": 25216, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 36978.0, + "resolved_value": 320025.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd99e21ba622e4f2a978332a" + "resolved_fact_key": "ledger_aggregate_fact_v2_fcc7bbe5d78c199fc6d856ca" }, { - "name": "mhclg.council_tax_stock.band_h@E12000009", + "name": "mhclg.council_tax_stock.band_a@E12000009", "status": "active", "matched_fact_count_overall": 10746, "matched_fact_count_at_or_before_period": 10638, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 6697.0, + "resolved_value": 422969.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f90a5f109dfd934a167bf0e0" + "resolved_fact_key": "ledger_aggregate_fact_v2_f23d41b29d6952c18d44dc26" } ] }, - "mhclg.council_tax_stock.total": { + "mhclg.council_tax_stock.band_b": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000001", + "name": "mhclg.council_tax_stock.band_b@E12000001", "status": "active", "matched_fact_count_overall": 4776, "matched_fact_count_at_or_before_period": 4728, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 1209414.0, + "resolved_value": 193309.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d0495e6e8e02785ad2236142" + "resolved_fact_key": "ledger_aggregate_fact_v2_f84be54967344adf03fab807" }, { - "name": "mhclg.council_tax_stock.total@E12000002", + "name": "mhclg.council_tax_stock.band_b@E12000002", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 3261518.0, + "resolved_value": 666970.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc1af92610b38c4757aea9cd" + "resolved_fact_key": "ledger_aggregate_fact_v2_fac49fea11fd3b1110a941c5" }, { - "name": "mhclg.council_tax_stock.total@E12000003", + "name": "mhclg.council_tax_stock.band_b@E12000003", "status": "active", "matched_fact_count_overall": 5970, "matched_fact_count_at_or_before_period": 5910, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2385734.0, + "resolved_value": 482052.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d97752a94900433af3ad7e6f" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8ef63f3e9b07a934c3f2df8" }, { - "name": "mhclg.council_tax_stock.total@E12000004", + "name": "mhclg.council_tax_stock.band_b@E12000004", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2103116.0, + "resolved_value": 478320.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef350c9b94fb54787fbca592" + "resolved_fact_key": "ledger_aggregate_fact_v2_f48dde558979080156b8c99f" }, { - "name": "mhclg.council_tax_stock.total@E12000005", + "name": "mhclg.council_tax_stock.band_b@E12000005", "status": "active", "matched_fact_count_overall": 11940, "matched_fact_count_at_or_before_period": 11820, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2499856.0, + "resolved_value": 625673.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f649a1ce99478b505d03ab91" + "resolved_fact_key": "ledger_aggregate_fact_v2_fc4a526b4ee56ed620ab4c14" }, { - "name": "mhclg.council_tax_stock.total@E12000006", + "name": "mhclg.council_tax_stock.band_b@E12000006", "status": "active", "matched_fact_count_overall": 17910, "matched_fact_count_at_or_before_period": 17730, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 2718131.0, + "resolved_value": 568914.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f27b18e8ecc0114a5b9e88e4" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe310977523bcaadf025f7f6" }, { - "name": "mhclg.council_tax_stock.total@E12000007", + "name": "mhclg.council_tax_stock.band_b@E12000007", "status": "active", "matched_fact_count_overall": 13134, "matched_fact_count_at_or_before_period": 13002, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 3601163.0, + "resolved_value": 463447.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f56db6353a3459ee98059504" + "resolved_fact_key": "ledger_aggregate_fact_v2_ffadb386ab954d99278ba891" }, { - "name": "mhclg.council_tax_stock.total@E12000008", + "name": "mhclg.council_tax_stock.band_b@E12000008", "status": "active", "matched_fact_count_overall": 25472, "matched_fact_count_at_or_before_period": 25216, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 3947536.0, + "resolved_value": 649092.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd4beff6e5a58b2ca5ff0b3a" + "resolved_fact_key": "ledger_aggregate_fact_v2_fb23fbffbee284d17da76489" }, { - "name": "mhclg.council_tax_stock.total@E12000009", + "name": "mhclg.council_tax_stock.band_b@E12000009", "status": "active", "matched_fact_count_overall": 10746, "matched_fact_count_at_or_before_period": 10638, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 2519799.0, + "resolved_value": 609286.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7339b440103ee7084920ea3" - } - ] - }, - "welshgov.council_tax_stock.band_a": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_a", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 194973.29, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_21e317eb3f397169fa2dc933" - } - ] - }, - "welshgov.council_tax_stock.band_b": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_b", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 285787.52, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_1db23c3de870c2f9704b9822" - } - ] - }, - "welshgov.council_tax_stock.band_c": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_c", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 301699.86, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8c0495e5862c06f0f268414" - } - ] - }, - "welshgov.council_tax_stock.band_d": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_d", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 225179.88, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_04e498c0e2dad39004885ea3" - } - ] - }, - "welshgov.council_tax_stock.band_e": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_e", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 185447.46, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8ca0bef4217724c1b6eafbb" - } - ] - }, - "welshgov.council_tax_stock.band_f": { - "status": "active", - "candidates": [ - { - "name": "welshgov.council_tax_stock.band_f", - "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, - "resolved_period": 2025, - "resolved_value": 114672.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9e314273b8264de7d24a7b6" + "resolved_fact_key": "ledger_aggregate_fact_v2_f84a549115340205a9ae8951" } ] }, - "welshgov.council_tax_stock.band_g": { + "mhclg.council_tax_stock.band_c": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_g", + "name": "mhclg.council_tax_stock.band_c@E12000001", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 52211.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_1ffc03853a7f22dbfdfd30ee" - } - ] - }, - "welshgov.council_tax_stock.band_h": { - "status": "active", - "candidates": [ + "resolved_value": 186703.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e5eaf3e7f4def06c8d938e5f" + }, { - "name": "welshgov.council_tax_stock.band_h", + "name": "mhclg.council_tax_stock.band_c@E12000002", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 12357.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_38b37ca6c167d44f1ee2b517" - } - ] - }, - "welshgov.council_tax_stock.band_i": { - "status": "active", - "candidates": [ + "resolved_value": 585587.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fc2f9b5b1813a71f580f85a4" + }, { - "name": "welshgov.council_tax_stock.band_i", + "name": "mhclg.council_tax_stock.band_c@E12000003", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 5305.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_f94d0825d8f1f21a02667aeb" - } - ] - }, - "welshgov.council_tax_stock.total": { - "status": "active", - "candidates": [ + "resolved_value": 408440.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe416e96e8e324e0e1647008" + }, { - "name": "welshgov.council_tax_stock.total", + "name": "mhclg.council_tax_stock.band_c@E12000004", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 1377633.03, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_69899dbf797a73ce0c05f13d" - } - ] - }, - "scotgov.council_tax_stock.band_a": { - "status": "active", - "candidates": [ + "resolved_value": 384470.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa1e7c770b7403c2a2663980" + }, { - "name": "scotgov.council_tax_stock.band_a", + "name": "mhclg.council_tax_stock.band_c@E12000005", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 498707.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_d16c53fe6a1c8f4f5886b7e5" - } - ] - }, - "scotgov.council_tax_stock.band_b": { - "status": "active", - "candidates": [ + "resolved_value": 503657.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffab2e562cd756fa9f44ac4c" + }, { - "name": "scotgov.council_tax_stock.band_b", + "name": "mhclg.council_tax_stock.band_c@E12000006", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 583705.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_2f95ec98ae61f9898bd47ed9" - } - ] - }, - "scotgov.council_tax_stock.band_c": { - "status": "active", - "candidates": [ + "resolved_value": 708146.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff565a1885420d902566f5be" + }, { - "name": "scotgov.council_tax_stock.band_c", + "name": "mhclg.council_tax_stock.band_c@E12000007", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 426388.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_c9781708df55dc5d197e6623" - } - ] - }, - "scotgov.council_tax_stock.band_d": { - "status": "active", - "candidates": [ + "resolved_value": 991205.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_eb754d4d8153e7497df94fa9" + }, { - "name": "scotgov.council_tax_stock.band_d", - "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "name": "mhclg.council_tax_stock.band_c@E12000008", + "status": "active", + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 369621.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_ae1fe03809a505b820479598" - } - ] - }, - "scotgov.council_tax_stock.band_e": { - "status": "active", - "candidates": [ + "resolved_value": 1024169.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_feb50a6c4dfa72419ef9e591" + }, { - "name": "scotgov.council_tax_stock.band_e", + "name": "mhclg.council_tax_stock.band_c@E12000009", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 366881.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_e83153e0de40fb74471c805f" + "resolved_value": 587214.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fff7d7ced3067ef09f8e6d12" } ] }, - "scotgov.council_tax_stock.band_f": { + "mhclg.council_tax_stock.band_d": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_f", + "name": "mhclg.council_tax_stock.band_d@E12000001", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 221282.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_b24b6409c1473600c03999ec" - } - ] - }, - "scotgov.council_tax_stock.band_g": { - "status": "active", - "candidates": [ + "resolved_value": 108432.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb2d7a086ad6d3c95a074ab0" + }, { - "name": "scotgov.council_tax_stock.band_g", + "name": "mhclg.council_tax_stock.band_d@E12000002", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 142084.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_c86494a855b00998122989d6" - } - ] - }, - "scotgov.council_tax_stock.band_h": { - "status": "active", - "candidates": [ + "resolved_value": 346489.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff0d7ad8c7d5d0d2f02702f0" + }, { - "name": "scotgov.council_tax_stock.band_h", + "name": "mhclg.council_tax_stock.band_d@E12000003", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 14481.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_60d9ae638eff29fc1c88907e" - } - ] - }, - "scotgov.council_tax_stock.total": { - "status": "active", - "candidates": [ + "resolved_value": 237496.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7c0b8b92776a6109a114a92" + }, { - "name": "scotgov.council_tax_stock.total", + "name": "mhclg.council_tax_stock.band_d@E12000004", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2623149.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_ca77a0f0a777ccba05e4bef9" - } - ] - }, - "scotgov.scottish_child_payment_spending": { - "status": "active", - "candidates": [ + "resolved_value": 238335.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa621220d1e5d193343634ca" + }, { - "name": "scotgov.scottish_child_payment_spending", + "name": "mhclg.council_tax_stock.band_d@E12000005", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 471000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_20b43b0f8f61e448f28895cf" - } - ] - }, - "ons.savings_interest_income": { - "status": "active", - "candidates": [ + "resolved_value": 288790.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff6f72e91c98eb23dfe9d09c" + }, { - "name": "ons.savings_interest_income", + "name": "mhclg.council_tax_stock.band_d@E12000006", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 95503000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_8de1806d1330bcb80a1f4988" - } - ] - }, - "ons.public_sector_employment": { - "status": "active", - "candidates": [ + "resolved_value": 485975.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd87126e89fd8a33383640f1" + }, { - "name": "ons.public_sector_employment", + "name": "mhclg.council_tax_stock.band_d@E12000007", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 6146000.0, - "resolved_fact_period": "2024-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff79b4e2301f564ec4203235" - } - ] - }, - "ons.land.land_value": { - "status": "active", - "candidates": [ + "resolved_value": 929941.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7dfce8ada24dca8651cdc12" + }, { - "name": "ons.land.land_value", + "name": "mhclg.council_tax_stock.band_d@E12000008", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 7117771000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_4daf8d1b8830f72bba924d56" - } - ] - }, - "ons.land.household_land_value": { - "status": "active", - "candidates": [ + "resolved_value": 807114.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8129a3bae48724ddc91e4ca" + }, { - "name": "ons.land.household_land_value", + "name": "mhclg.council_tax_stock.band_d@E12000009", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 4559831000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_0e5f9867ab377dffd8a8941f" + "resolved_value": 404568.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f3dcc56f346a75bfa16137" } ] }, - "ons.land.corporate_land_value": { + "mhclg.council_tax_stock.band_e": { "status": "active", "candidates": [ { - "name": "ons.land.corporate_land_value", + "name": "mhclg.council_tax_stock.band_e@E12000001", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 2103053000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ab561a17be0af52de30cca88" - } - ] - }, - "slc.repayments.devolved_total": { - "status": "no_fact_at_or_before_period", - "candidates": [ + "resolved_value": 58932.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e767a90e1f4f3985379189f5" + }, { - "name": "slc.repayments.devolved_total", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "slc.repayments.england_total_higher_education": { - "status": "active", - "candidates": [ + "name": "mhclg.council_tax_stock.band_e@E12000002", + "status": "active", + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 207825.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9b8ef4202908453655767f0" + }, { - "name": "slc.repayments.england_total_higher_education", + "name": "mhclg.council_tax_stock.band_e@E12000003", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 5018231834.949999, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b947d1f3c3659d252194c102" - } - ] - }, - "slc.repayments.england_plan_1": { - "status": "active", - "candidates": [ + "resolved_value": 152517.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fbb09c3c4f80ba784375aa37" + }, { - "name": "slc.repayments.england_plan_1", + "name": "mhclg.council_tax_stock.band_e@E12000004", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 1852699178.55, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d9680e6eaf243227fed5ef2" - } - ] - }, - "slc.repayments.england_plan_2": { - "status": "active", - "candidates": [ + "resolved_value": 149931.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fec984442b918005ccc92238" + }, { - "name": "slc.repayments.england_plan_2", + "name": "mhclg.council_tax_stock.band_e@E12000005", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2778253361.64, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_882329821c90dc683aa778d8" - } - ] - }, - "slc.repayments.england_postgraduate": { - "status": "active", - "candidates": [ + "resolved_value": 185672.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_d83f9067bfa886482b6a5be7" + }, { - "name": "slc.repayments.england_postgraduate", + "name": "mhclg.council_tax_stock.band_e@E12000006", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 346409713.95000005, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ac1b07c69f1e1baa2a0fb787" - } - ] - }, - "slc.repayments.england_plan_5": { - "status": "active", - "candidates": [ + "resolved_value": 301723.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb2e48afaa19a026d3d2dbf9" + }, { - "name": "slc.repayments.england_plan_5", + "name": "mhclg.council_tax_stock.band_e@E12000007", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 40869580.81, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_496af6b8fe31c71c43f1d292" - } - ] - }, - "slc.borrowers.plan_2_above_threshold": { - "status": "active", - "candidates": [ + "resolved_value": 551952.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe53b4ade27bba47669221bb" + }, { - "name": "slc.borrowers.plan_2_above_threshold", + "name": "mhclg.council_tax_stock.band_e@E12000008", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 4460000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_02288c19caeae900fdaf1e0d" - } - ] - }, - "slc.borrowers.plan_2_liable": { - "status": "active", - "candidates": [ + "resolved_value": 529137.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff8b7b878381855ff02392c8" + }, { - "name": "slc.borrowers.plan_2_liable", + "name": "mhclg.council_tax_stock.band_e@E12000009", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 9710000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_37387933e73bcc8c1e04cf78" + "resolved_value": 274120.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd8affa54b589a8f8dfa76e1" } ] }, - "slc.borrowers.plan_5_above_threshold": { + "mhclg.council_tax_stock.band_f": { "status": "active", "candidates": [ { - "name": "slc.borrowers.plan_5_above_threshold", + "name": "mhclg.council_tax_stock.band_f@E12000001", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 35000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd16b085f81ef7708a00511e" - } - ] - }, - "slc.borrowers.plan_5_liable": { - "status": "active", - "candidates": [ + "resolved_value": 25729.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f1a656e56ed4ec922ab1be8a" + }, { - "name": "slc.borrowers.plan_5_liable", + "name": "mhclg.council_tax_stock.band_f@E12000002", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 230000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_73ff136d820950ea404ddb6b" - } - ] - }, - "slc.support.maintenance_loan_recipients": { - "status": "active", - "candidates": [ + "resolved_value": 100117.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f934ec4447a2decb7d93153c" + }, { - "name": "slc.support.maintenance_loan_recipients", + "name": "mhclg.council_tax_stock.band_f@E12000003", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 1159761.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f03bd7a10d0eee9917a3a199" - } - ] - }, - "slc.support.maintenance_loan_spend": { - "status": "active", - "candidates": [ + "resolved_value": 73172.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fed1e74402841596ec02537f" + }, { - "name": "slc.support.maintenance_loan_spend", + "name": "mhclg.council_tax_stock.band_f@E12000004", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 8591659718.080004, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2900e25d7ee90f79fb3b87b9" - } - ] - }, - "slc.support.parents_learning_allowance_recipients": { - "status": "active", - "candidates": [ + "resolved_value": 71418.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f992d8c87d194b0dfb07b0fa" + }, { - "name": "slc.support.parents_learning_allowance_recipients", + "name": "mhclg.council_tax_stock.band_f@E12000005", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 99645.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d5df1c69846ab2fd3d0e50e1" - } - ] - }, - "slc.support.parents_learning_allowance_spend": { - "status": "active", - "candidates": [ + "resolved_value": 102077.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f49f0636d79cb28dcc85e1" + }, + { + "name": "mhclg.council_tax_stock.band_f@E12000006", + "status": "active", + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", + "resolved_period": 2025, + "resolved_value": 166744.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e672d9b03691ddd1faac694d" + }, { - "name": "slc.support.parents_learning_allowance_spend", + "name": "mhclg.council_tax_stock.band_f@E12000007", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 181421659.32, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_72028ce00b9569deec79d6e6" - } - ] - }, - "slc.support.adult_dependants_grant_recipients": { - "status": "active", - "candidates": [ + "resolved_value": 279261.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef478a0ef6ff0cb78a65dcaa" + }, { - "name": "slc.support.adult_dependants_grant_recipients", + "name": "mhclg.council_tax_stock.band_f@E12000008", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 18611.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_adc83b5d137ecb48fed77064" - } - ] - }, - "slc.support.adult_dependants_grant_spend": { - "status": "active", - "candidates": [ + "resolved_value": 325815.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb02357269b3d262a700cf5f" + }, { - "name": "slc.support.adult_dependants_grant_spend", + "name": "mhclg.council_tax_stock.band_f@E12000009", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 55364916.81, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_5d42660596c9088248e41e90" + "resolved_value": 139412.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb77e2f50e126802cff79f21" } ] }, - "dwp.uc.households": { + "mhclg.council_tax_stock.band_g": { "status": "active", "candidates": [ { - "name": "dwp.uc.households", + "name": "mhclg.council_tax_stock.band_g@E12000001", "status": "active", - "matched_fact_count_overall": 120, - "matched_fact_count_at_or_before_period": 120, - "matched_fact_count_in_source_window": 120, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 6197311.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_71c060f3f2a732e2f836a5d8" - } - ] - }, - "hmrc.tfc.government_top_up": { - "status": "active", - "candidates": [ + "resolved_value": 14062.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f80042add7dbd445217cde1a" + }, { - "name": "hmrc.tfc.government_top_up", + "name": "mhclg.council_tax_stock.band_g@E12000002", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 599800000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_988715985f9e98bbb332e83d" - } - ] - }, - "hmrc.tfc.children_with_used_accounts": { - "status": "active", - "candidates": [ + "resolved_value": 62587.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffc555374f59e3667468b086" + }, { - "name": "hmrc.tfc.children_with_used_accounts", + "name": "mhclg.council_tax_stock.band_g@E12000003", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 1151515.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_7aa1c663447037b35ea1c999" - } - ] - }, - "dfe.funded_childcare.working_parent_children_2_to_4": { - "status": "active", - "candidates": [ + "resolved_value": 40487.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f290bf6f13fa468c2acf0be2" + }, { - "name": "dfe.funded_childcare.working_parent_children_2_to_4", + "name": "mhclg.council_tax_stock.band_g@E12000004", "status": "active", - "matched_fact_count_overall": 11, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 621482.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_a57a0c03ac43b62dde04fabd" - } - ] - }, - "dfe.funded_childcare.early_learning_2_year_olds": { - "status": "active", - "candidates": [ + "resolved_value": 37892.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f69d9fecd8d273243af03685" + }, { - "name": "dfe.funded_childcare.early_learning_2_year_olds", + "name": "mhclg.council_tax_stock.band_g@E12000005", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 11, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 95031.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_a2b30af28303935159ba0edc" - } - ] - }, - "dfe.funded_childcare.universal_only_children": { - "status": "active", - "candidates": [ + "resolved_value": 60209.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ec75efe3a83bc6d9c25d7ae1" + }, { - "name": "dfe.funded_childcare.universal_only_children", + "name": "mhclg.council_tax_stock.band_g@E12000006", "status": "active", - "matched_fact_count_overall": 770, - "matched_fact_count_at_or_before_period": 686, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 396965.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_471573def13ebdc67ff1f40a" - } - ] - }, - "dft.bus_fare_receipts.england": { - "status": "active", - "candidates": [ + "resolved_value": 108700.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd2a0529ed0a7cf9532ef8ea" + }, { - "name": "dft.bus_fare_receipts.england", + "name": "mhclg.council_tax_stock.band_g@E12000007", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 3612036036.2194014, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ece7c3d283b6de43b30389f", - "uprating": { - "index": "dft.local_bus_fares_index", - "factor": "1.05695792880259", - "value_before_uprating": "3417388656.43538" - } - } - ] - }, - "dft.bus_net_support.england": { - "status": "active", - "candidates": [ + "resolved_value": 207056.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7d99e8a41825169a450a9ed" + }, { - "name": "dft.bus_net_support.england", + "name": "mhclg.council_tax_stock.band_g@E12000008", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 3024904320.8399997, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a12dfcdc0662c8a5e48bf003" - } - ] - }, - "dft.bus_fare_receipts.london": { - "status": "active", - "candidates": [ + "resolved_value": 255206.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fda73631af17107d741fed93" + }, { - "name": "dft.bus_fare_receipts.london", + "name": "mhclg.council_tax_stock.band_g@E12000009", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 1347434943.01459, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_33611c64d2048fe660501802", - "uprating": { - "index": "dft.local_bus_fares_index", - "factor": "1", - "value_before_uprating": "1347434943.01459" - } + "resolved_value": 75533.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ddffd3467540ebe8f71dc050" } ] }, - "dft.bus_net_support.london": { + "mhclg.council_tax_stock.band_h": { "status": "active", "candidates": [ { - "name": "dft.bus_net_support.london", + "name": "mhclg.council_tax_stock.band_h@E12000001", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 1130214000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d8e40cee2fc723b719ff4680" - } - ] - }, - "dft.bus_fare_receipts.england_outside_london": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_fare_receipts.england_outside_london", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." - } - ] - }, - "dft.bus_net_support.england_outside_london": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_net_support.england_outside_london", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." - } - ] - }, - "dft.bus_fare_receipts.uk": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_fare_receipts.uk", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "BUS05i publishes no UK total and Microcosm declares no method to construct one." - } - ] - }, - "dft.bus_net_support.uk": { - "status": "signed_excluded", - "candidates": [ + "resolved_value": 1151.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4150e637c1d82a68bb2a28" + }, { - "name": "dft.bus_net_support.uk", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "BUS05i publishes no UK total and no England-to-UK uplift is declared. Net support binds instead as four country legs whose scopes differ: DfT BUS05bi net support (England, operators' view), Scottish Transport Statistics all government support (Scotland), StatsWales revenue outturn gross expenditure on concessionary fares and support to operators through local authorities only (Wales: no operator-side series and no Welsh Government grants outside the outturn), and the NITHC accounts' Public Service Obligation plus concessionary compensation as one bus-plus-rail cell excluding GBP 53.2m of other revenue funding (Northern Ireland). The legs are bound on their own terms; they are not a UK total under another name." - } - ] - }, - "obr.fuel_duties_cars": { - "status": "active", - "candidates": [ + "name": "mhclg.council_tax_stock.band_h@E12000002", + "status": "active", + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 6230.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f742ed87e05f38e0a20ba028" + }, { - "name": "obr.fuel_duties_cars", + "name": "mhclg.council_tax_stock.band_h@E12000003", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 14400000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de6554fe8ab7b481035a432a" - } - ] - }, - "orr.rail_government_support": { - "status": "active", - "candidates": [ + "resolved_value": 3022.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd393adec42be55cfefb3400" + }, { - "name": "orr.rail_government_support", + "name": "mhclg.council_tax_stock.band_h@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 21621100549.34064, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b16b9b3f2329455f907f9ccc" - } - ] - }, - "ons.household_energy_expenditure": { - "status": "signed_excluded", - "candidates": [ + "resolved_value": 2779.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe1b32af9c019b0fa366ea83" + }, { - "name": "ons.household_energy_expenditure", - "status": "signed_excluded", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, - "signed_rationale": "ONS Consumer Trends COICOP 04.5 (electricity, gas and other fuels) carries liquid and solid fuels the frame does not model; chronicle #271 (chronicle#270) published the 04.5.1 electricity and 04.5.2 gas sub-classes, which ons.household_electricity_expenditure and ons.household_gas_expenditure bind per fuel on the frame's own columns. The total row is retained in the contract for registry parity and signed out here (microcosm#890 F1)." - } - ] - }, - "ons.household_electricity_expenditure": { - "status": "active", - "candidates": [ + "name": "mhclg.council_tax_stock.band_h@E12000005", + "status": "active", + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", + "resolved_period": 2025, + "resolved_value": 5285.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f086bebb12518f66fdd27be8" + }, { - "name": "ons.household_electricity_expenditure", + "name": "mhclg.council_tax_stock.band_h@E12000006", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 26522000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_69cd660b943ae8f21761f76a" - } - ] - }, - "ons.household_gas_expenditure": { - "status": "active", - "candidates": [ + "resolved_value": 13447.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb031812869aaf579b6d5b62" + }, { - "name": "ons.household_gas_expenditure", + "name": "mhclg.council_tax_stock.band_h@E12000007", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 15339000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b56be49c552300f6c02fc559" - } - ] - }, - "scotgov.bus.passenger_revenue": { - "status": "active", - "candidates": [ + "resolved_value": 59569.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb5c13d22ffe09151cf3b4f8" + }, { - "name": "scotgov.bus.passenger_revenue", + "name": "mhclg.council_tax_stock.band_h@E12000008", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 391000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c4269bb83534f1e46f5801c1" - } - ] - }, - "scotgov.bus.government_support": { - "status": "active", - "candidates": [ + "resolved_value": 36978.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd99e21ba622e4f2a978332a" + }, { - "name": "scotgov.bus.government_support", + "name": "mhclg.council_tax_stock.band_h@E12000009", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 499000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ceb60fd41d0f5587be94c234" + "resolved_value": 6697.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f90a5f109dfd934a167bf0e0" } ] }, - "welshgov.bus.public_support": { + "mhclg.council_tax_stock.total": { "status": "active", "candidates": [ { - "name": "welshgov.bus.public_support", + "name": "mhclg.council_tax_stock.total@E12000001", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 131489970.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a10fcfec7cb458fa0c8c7f10" - } - ] - }, - "dfi_ni.bus.passenger_receipts": { - "status": "active", - "candidates": [ + "resolved_value": 1209414.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_d0495e6e8e02785ad2236142" + }, { - "name": "dfi_ni.bus.passenger_receipts", + "name": "mhclg.council_tax_stock.total@E12000002", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 150082817.48999995, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f72989614e0c5faaeeabbb" - } - ] - }, - "nithc.public_transport_support": { - "status": "active", - "candidates": [ + "resolved_value": 3261518.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fc1af92610b38c4757aea9cd" + }, { - "name": "nithc.public_transport_support", + "name": "mhclg.council_tax_stock.total@E12000003", "status": "active", - "matched_fact_count_overall": 4, - "matched_fact_count_at_or_before_period": 4, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 111700000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_be8eb7011b6f65fa65d52fcb" - } - ] - }, - "dwp.uc.households_lcwra_element": { - "status": "active", - "candidates": [ + "resolved_value": 2385734.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_d97752a94900433af3ad7e6f" + }, { - "name": "dwp.uc.households_lcwra_element", + "name": "mhclg.council_tax_stock.total@E12000004", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2272425.1666666665, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f59149c4c514e1acffb728a8" - } - ] - }, - "dwp.uc.households_carer_element": { - "status": "active", - "candidates": [ + "resolved_value": 2103116.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef350c9b94fb54787fbca592" + }, { - "name": "dwp.uc.households_carer_element", + "name": "mhclg.council_tax_stock.total@E12000005", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 1078514.5, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d56ddfa58d7ebb3ff0178b0a" - } - ] - }, - "dwp.uc.households_housing_element": { - "status": "active", - "candidates": [ + "resolved_value": 2499856.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f649a1ce99478b505d03ab91" + }, { - "name": "dwp.uc.households_housing_element", + "name": "mhclg.council_tax_stock.total@E12000006", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 4037650.3333333335, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_04b7ec6d195e6682f0421672" - } - ] - }, - "dwp.uc.households_housing_element_social_rented": { - "status": "active", - "candidates": [ + "resolved_value": 2718131.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f27b18e8ecc0114a5b9e88e4" + }, { - "name": "dwp.uc.households_housing_element_social_rented", + "name": "mhclg.council_tax_stock.total@E12000007", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 2354587.5833333335, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_109598f6aaa42fe1387d30d1" - } - ] - }, - "dwp.uc.households_housing_element_private_rented": { - "status": "active", - "candidates": [ + "resolved_value": 3601163.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f56db6353a3459ee98059504" + }, { - "name": "dwp.uc.households_housing_element_private_rented", + "name": "mhclg.council_tax_stock.total@E12000008", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1570545.4166666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7a31b88dfcd4b3d0c758a1c3" - } - ] - }, - "dwp.uc.households_childcare_element": { - "status": "active", - "candidates": [ + "resolved_value": 3947536.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd4beff6e5a58b2ca5ff0b3a" + }, { - "name": "dwp.uc.households_childcare_element", + "name": "mhclg.council_tax_stock.total@E12000009", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 178666.66666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0c1aa0cc56d86c50d6b2560a" + "resolved_value": 2519799.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7339b440103ee7084920ea3" } ] }, - "dwp.uc.households_with_deduction": { + "welshgov.council_tax_stock.band_a": { "status": "active", "candidates": [ { - "name": "dwp.uc.households_with_deduction", + "name": "welshgov.council_tax_stock.band_a", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "matched_fact_count_in_source_window": 10, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 3130000.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7bfdb41a462c417535602d2" + "resolved_value": 194973.29, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_21e317eb3f397169fa2dc933" } ] }, - "obr.universal_credit": { + "welshgov.council_tax_stock.band_b": { "status": "active", "candidates": [ { - "name": "obr.universal_credit", + "name": "welshgov.council_tax_stock.band_b", "status": "active", - "matched_fact_count_overall": 14, - "matched_fact_count_at_or_before_period": 4, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 79286349139.54411, + "resolved_value": 285787.52, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" + "resolved_fact_key": "ledger_aggregate_fact_v2_1db23c3de870c2f9704b9822" } ] }, - "dwp.hb.households": { + "welshgov.council_tax_stock.band_c": { "status": "active", "candidates": [ { - "name": "dwp.hb.households", + "name": "welshgov.council_tax_stock.band_c", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 1685702.9166666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f2ecf4d38ef4dfc796336538" + "resolved_value": 301699.86, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_c8c0495e5862c06f0f268414" } ] }, - "dwp.hb.households_social_rented": { + "welshgov.council_tax_stock.band_d": { "status": "active", "candidates": [ { - "name": "dwp.hb.households_social_rented", + "name": "welshgov.council_tax_stock.band_d", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 1381089.75, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_40b45c74a40b8d085a8c28e2" + "resolved_value": 225179.88, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_04e498c0e2dad39004885ea3" } ] }, - "dwp.hb.households_private_rented": { + "welshgov.council_tax_stock.band_e": { "status": "active", "candidates": [ { - "name": "dwp.hb.households_private_rented", + "name": "welshgov.council_tax_stock.band_e", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 304422.6666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_02281858b7b0d71477e429f3" + "resolved_value": 185447.46, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e8ca0bef4217724c1b6eafbb" } ] }, - "dwp.benefit_cap.capped_households_up_to_100": { + "welshgov.council_tax_stock.band_f": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_up_to_100", + "name": "welshgov.council_tax_stock.band_f", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 38402.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_220b82ab05bec494e6dc9fe9" + "resolved_value": 114672.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9e314273b8264de7d24a7b6" } ] }, - "dwp.benefit_cap.capped_households_100_01_to_200": { + "welshgov.council_tax_stock.band_g": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_100_01_to_200", + "name": "welshgov.council_tax_stock.band_g", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 24274.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_4a9e2cc181aee62e1eccd188" + "resolved_value": 52211.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_1ffc03853a7f22dbfdfd30ee" } ] }, - "dwp.benefit_cap.capped_households_200_01_to_300": { + "welshgov.council_tax_stock.band_h": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_200_01_to_300", + "name": "welshgov.council_tax_stock.band_h", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 16240.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_5ae8289242eabcffab23f32f" + "resolved_value": 12357.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_38b37ca6c167d44f1ee2b517" } ] }, - "dwp.benefit_cap.capped_households_300_01_to_400": { + "welshgov.council_tax_stock.band_i": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_300_01_to_400", + "name": "welshgov.council_tax_stock.band_i", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 10562.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_a503d4e938aaf386720b96c4" + "resolved_value": 5305.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_f94d0825d8f1f21a02667aeb" } ] }, - "dwp.benefit_cap.capped_households_400_01_to_500": { + "welshgov.council_tax_stock.total": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_400_01_to_500", + "name": "welshgov.council_tax_stock.total", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, "resolved_period": 2025, - "resolved_value": 7813.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_df764409769b2078c69ff113" + "resolved_value": 1377633.03, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_69899dbf797a73ce0c05f13d" } ] }, - "dwp.benefit_cap.capped_households_500_01_to_600": { + "scotgov.council_tax_stock.band_a": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_500_01_to_600", + "name": "scotgov.council_tax_stock.band_a", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 4431.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d0e936b240ba62209777ee3" + "resolved_value": 498707.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_d16c53fe6a1c8f4f5886b7e5" } ] }, - "dwp.benefit_cap.capped_households_600_01_to_700": { + "scotgov.council_tax_stock.band_b": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_600_01_to_700", + "name": "scotgov.council_tax_stock.band_b", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 3116.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d68398dd88958a8700dcfac" + "resolved_value": 583705.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_2f95ec98ae61f9898bd47ed9" } ] }, - "dwp.benefit_cap.capped_households_700_01_to_800": { + "scotgov.council_tax_stock.band_c": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_700_01_to_800", + "name": "scotgov.council_tax_stock.band_c", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 1902.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_999288b0fa67d7f657810a11" + "resolved_value": 426388.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_c9781708df55dc5d197e6623" } ] }, - "dwp.benefit_cap.capped_households_800_01_to_900": { + "scotgov.council_tax_stock.band_d": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_800_01_to_900", + "name": "scotgov.council_tax_stock.band_d", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 1328.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_b7a2d0cec131abfd0cb81ba0" + "resolved_value": 369621.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_ae1fe03809a505b820479598" } ] }, - "dwp.benefit_cap.capped_households_900_01_to_1000": { + "scotgov.council_tax_stock.band_e": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_900_01_to_1000", + "name": "scotgov.council_tax_stock.band_e", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 824.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_80c8fa82f3e07357e677ae93" + "resolved_value": 366881.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_e83153e0de40fb74471c805f" } ] }, - "dwp.benefit_cap.capped_households_1000_01_to_1100": { + "scotgov.council_tax_stock.band_f": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1000_01_to_1100", + "name": "scotgov.council_tax_stock.band_f", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 497.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf55cee33404d2283800b2b5" + "resolved_value": 221282.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_b24b6409c1473600c03999ec" } ] }, - "dwp.benefit_cap.capped_households_1100_01_to_1200": { + "scotgov.council_tax_stock.band_g": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1100_01_to_1200", + "name": "scotgov.council_tax_stock.band_g", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 380.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_6f836a33391f4352151bd27f" + "resolved_value": 142084.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_c86494a855b00998122989d6" } ] }, - "dwp.benefit_cap.capped_households_1200_01_to_1300": { + "scotgov.council_tax_stock.band_h": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1200_01_to_1300", + "name": "scotgov.council_tax_stock.band_h", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 239.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad08714cf39be9ccf0450cf2" + "resolved_value": 14481.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_60d9ae638eff29fc1c88907e" } ] }, - "dwp.benefit_cap.capped_households_1300_01_and_above": { + "scotgov.council_tax_stock.total": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1300_01_and_above", + "name": "scotgov.council_tax_stock.total", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 627.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_a3fee6cdec1b46a15a3b1434" + "resolved_value": 2623149.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_ca77a0f0a777ccba05e4bef9" } ] }, - "hmrc.cgt.taxpayers_by_age_band": { + "scotgov.scottish_child_payment_spending": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_age_band.age_0_to_15", - "status": "signed_excluded", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "signed_row": { - "dimension": "age_band", - "value": "age_0_to_15" - }, - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_16_to_24", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 4000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_8c3d294de4cbdbe292815164" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_25_to_34", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 27000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cc8ef619f52f7f44a885ce52" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_35_to_44", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 65000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_8554e7f842699a5f49816a0d" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_45_to_54", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 98000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_794376b60fba0684412fdff8" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_55_to_64", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 144000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_0d6b6c36290ab598f74f6669" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_65_to_74", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 125000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a725972fe4ee87a3bddee1cf" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_75_to_84", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 68000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_1e4899d950c2b2be8ae21459" - }, - { - "name": "hmrc.cgt.taxpayers_by_age_band.age_85_plus", + "name": "scotgov.scottish_child_payment_spending", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 19000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7c419e2a82d25fae0127fd1d" + "resolved_value": 471000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_20b43b0f8f61e448f28895cf" } ] }, - "hmrc.cgt.gains_by_age_band": { + "ons.savings_interest_income": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_0_to_15", - "status": "signed_excluded", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "signed_row": { - "dimension": "age_band", - "value": "age_0_to_15" - }, - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "name": "hmrc.cgt.gains_by_age_band.age_16_to_24", + "name": "ons.savings_interest_income", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 319000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_af584dedce4184d834502e56" - }, + "resolved_value": 95503000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_8de1806d1330bcb80a1f4988" + } + ] + }, + "ons.public_sector_employment": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_25_to_34", + "name": "ons.public_sector_employment", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 2499000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_40c8b42d3904c8eb44297559" - }, + "resolved_value": 6146000.0, + "resolved_fact_period": "2024-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff79b4e2301f564ec4203235" + } + ] + }, + "ons.land.land_value": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_35_to_44", + "name": "ons.land.land_value", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 11775000000.0, + "resolved_value": 7117771000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_375b4cb880dcb4caacc5f003" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_4daf8d1b8830f72bba924d56" + } + ] + }, + "ons.land.household_land_value": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_45_to_54", + "name": "ons.land.household_land_value", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 28422000000.0, + "resolved_value": 4559831000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_567f8babf11f6356f72398de" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_0e5f9867ab377dffd8a8941f" + } + ] + }, + "ons.land.corporate_land_value": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_55_to_64", + "name": "ons.land.corporate_land_value", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 38118000000.0, + "resolved_value": 2103053000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_38da5aa08efc20c32951a860" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ab561a17be0af52de30cca88" + } + ] + }, + "slc.repayments.devolved_total": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_65_to_74", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 24260000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_69e2dec98e4cdbe34c3a0572" - }, + "name": "slc.repayments.devolved_total", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "slc.repayments.england_total_higher_education": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_75_to_84", + "name": "slc.repayments.england_total_higher_education", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11736000000.0, + "resolved_value": 5018231834.949999, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_9d0fb4e1a0c63f6d06b73e61" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b947d1f3c3659d252194c102" + } + ] + }, + "slc.repayments.england_plan_1": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_age_band.age_85_plus", + "name": "slc.repayments.england_plan_1", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2076000000.0, + "resolved_value": 1852699178.55, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ca2b09a93c8a40ea4766b341" + "resolved_fact_key": "ledger_aggregate_fact_v2_1d9680e6eaf243227fed5ef2" } ] }, - "hmrc.cgt.tax_by_age_band": { + "slc.repayments.england_plan_2": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_0_to_15", - "status": "signed_excluded", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "signed_row": { - "dimension": "age_band", - "value": "age_0_to_15" - }, - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "name": "hmrc.cgt.tax_by_age_band.age_16_to_24", + "name": "slc.repayments.england_plan_2", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 59000000.0, + "resolved_value": 2778253361.64, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_5e45e49cdf5771a4f3dbc0c6" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_882329821c90dc683aa778d8" + } + ] + }, + "slc.repayments.england_postgraduate": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_25_to_34", + "name": "slc.repayments.england_postgraduate", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 456000000.0, + "resolved_value": 346409713.95000005, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_4f0a20f8646020c518ec1a6c" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ac1b07c69f1e1baa2a0fb787" + } + ] + }, + "slc.repayments.england_plan_5": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_35_to_44", + "name": "slc.repayments.england_plan_5", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 2246000000.0, + "resolved_value": 40869580.81, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_041101c10e8ee3a674596ab2" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_496af6b8fe31c71c43f1d292" + } + ] + }, + "slc.borrowers.plan_2_above_threshold": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_45_to_54", + "name": "slc.borrowers.plan_2_above_threshold", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 5522000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c678a6f27d3dc149131419ee" - }, + "resolved_value": 4460000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_02288c19caeae900fdaf1e0d" + } + ] + }, + "slc.borrowers.plan_2_liable": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_55_to_64", + "name": "slc.borrowers.plan_2_liable", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 7152000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_76990ed6855fce16817d5289" - }, + "resolved_value": 9710000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_37387933e73bcc8c1e04cf78" + } + ] + }, + "slc.borrowers.plan_5_above_threshold": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_65_to_74", + "name": "slc.borrowers.plan_5_above_threshold", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 4409000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d4b0b5873bbe5bce9c14381" - }, + "resolved_value": 35000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_dd16b085f81ef7708a00511e" + } + ] + }, + "slc.borrowers.plan_5_liable": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_75_to_84", + "name": "slc.borrowers.plan_5_liable", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 2260000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_9c1150dfbd7f4f3b6235050b" - }, + "resolved_value": 230000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_73ff136d820950ea404ddb6b" + } + ] + }, + "slc.support.maintenance_loan_recipients": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.tax_by_age_band.age_85_plus", + "name": "slc.support.maintenance_loan_recipients", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 390000000.0, + "resolved_value": 1159761.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e60df0c2438533341e2f4b08" + "resolved_fact_key": "ledger_aggregate_fact_v2_f03bd7a10d0eee9917a3a199" } ] }, - "hmrc.cgt.taxpayers_by_region": { + "slc.support.maintenance_loan_spend": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000001", + "name": "slc.support.maintenance_loan_spend", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 11321.91780821918, + "resolved_value": 8591659718.080004, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_06f4adc777a4a3036026872f" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_2900e25d7ee90f79fb3b87b9" + } + ] + }, + "slc.support.parents_learning_allowance_recipients": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000002", + "name": "slc.support.parents_learning_allowance_recipients", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 41513.69863013699, + "resolved_value": 99645.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_9c0d0cc201d3d0f86df9f485" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_d5df1c69846ab2fd3d0e50e1" + } + ] + }, + "slc.support.parents_learning_allowance_spend": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000003", + "name": "slc.support.parents_learning_allowance_spend", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 32078.767123287675, + "resolved_value": 181421659.32, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_abfee7a635221f3a6573857f" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_72028ce00b9569deec79d6e6" + } + ] + }, + "slc.support.adult_dependants_grant_recipients": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000004", + "name": "slc.support.adult_dependants_grant_recipients", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 31135.273972602743, + "resolved_value": 18611.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d8b059af35df8fc34df0ebfa" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_adc83b5d137ecb48fed77064" + } + ] + }, + "slc.support.adult_dependants_grant_spend": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000005", + "name": "slc.support.adult_dependants_grant_spend", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 33022.260273972606, + "resolved_value": 55364916.81, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d003284169d6847765c66221" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_5d42660596c9088248e41e90" + } + ] + }, + "dwp.uc.households": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000006", + "name": "dwp.uc.households", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 120, + "matched_fact_count_at_or_before_period": 120, + "matched_fact_count_in_source_window": 120, "resolved_period": 2025, - "resolved_value": 58496.57534246576, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a48acd5e86822a82360de3c3" - }, + "resolved_value": 6197311.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_71c060f3f2a732e2f836a5d8" + } + ] + }, + "hmrc.tfc.government_top_up": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000007", + "name": "hmrc.tfc.government_top_up", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 106614.72602739726, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7bde136c5103f6b31dc478ef" - }, + "resolved_value": 599800000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_988715985f9e98bbb332e83d" + } + ] + }, + "hmrc.tfc.children_with_used_accounts": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000008", + "name": "hmrc.tfc.children_with_used_accounts", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 114162.67123287672, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_228fb212eb226981e6213fb1" - }, + "resolved_value": 1151515.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_7aa1c663447037b35ea1c999" + } + ] + }, + "dfe.funded_childcare.working_parent_children_2_to_4": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@E12000009", + "name": "dfe.funded_childcare.working_parent_children_2_to_4", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 11, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 60383.56164383562, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_af8dd206a47ffbc3651ece3b" - }, + "resolved_value": 621482.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_a57a0c03ac43b62dde04fabd" + } + ] + }, + "dfe.funded_childcare.early_learning_2_year_olds": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@W92000004", + "name": "dfe.funded_childcare.early_learning_2_year_olds", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 11, "resolved_period": 2025, - "resolved_value": 16982.87671232877, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c3fb868cb38397d0420cd136" - }, + "resolved_value": 95031.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_a2b30af28303935159ba0edc" + } + ] + }, + "dfe.funded_childcare.universal_only_children": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@S92000003", + "name": "dfe.funded_childcare.universal_only_children", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 770, + "matched_fact_count_at_or_before_period": 686, "resolved_period": 2025, - "resolved_value": 34909.24657534247, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e3b5a134b920d7bcf071dc5c" - }, + "resolved_value": 396965.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_471573def13ebdc67ff1f40a" + } + ] + }, + "dft.bus_fare_receipts.england": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.taxpayers_by_region@N92000002", + "name": "dft.bus_fare_receipts.england", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 9434.931506849316, + "resolved_value": 3612036036.2194014, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2779d0ba66235d3ec59280b8" + "resolved_fact_key": "ledger_aggregate_fact_v2_2ece7c3d283b6de43b30389f", + "uprating": { + "index": "dft.local_bus_fares_index", + "factor": "1.05695792880259", + "value_before_uprating": "3417388656.43538" + } } ] }, - "hmrc.cgt.gains_by_region": { + "dft.bus_net_support.england": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000001", + "name": "dft.bus_net_support.england", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 1497797150.3974364, + "resolved_value": 3024904320.8399997, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c56796163e95a924ef066aeb" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_a12dfcdc0662c8a5e48bf003" + } + ] + }, + "dft.bus_fare_receipts.london": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000002", + "name": "dft.bus_fare_receipts.london", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 8790074083.38308, + "resolved_value": 1347434943.01459, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_07d5a851c664d71dad2233c6" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_33611c64d2048fe660501802", + "uprating": { + "index": "dft.local_bus_fares_index", + "factor": "1", + "value_before_uprating": "1347434943.01459" + } + } + ] + }, + "dft.bus_net_support.london": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000003", + "name": "dft.bus_net_support.london", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 6970985861.949795, + "resolved_value": 1130214000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6b4137649b34773c10d9731d" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_d8e40cee2fc723b719ff4680" + } + ] + }, + "dft.bus_fare_receipts.england_outside_london": { + "status": "signed_excluded", + "candidates": [ + { + "name": "dft.bus_fare_receipts.england_outside_london", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." + } + ] + }, + "dft.bus_net_support.england_outside_london": { + "status": "signed_excluded", + "candidates": [ + { + "name": "dft.bus_net_support.england_outside_london", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." + } + ] + }, + "dft.bus_fare_receipts.uk": { + "status": "signed_excluded", + "candidates": [ + { + "name": "dft.bus_fare_receipts.uk", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "BUS05i publishes no UK total and Microcosm declares no method to construct one." + } + ] + }, + "dft.bus_net_support.uk": { + "status": "signed_excluded", + "candidates": [ + { + "name": "dft.bus_net_support.uk", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "BUS05i publishes no UK total and no England-to-UK uplift is declared. Net support binds instead as four country legs whose scopes differ: DfT BUS05bi net support (England, operators' view), Scottish Transport Statistics all government support (Scotland), StatsWales revenue outturn gross expenditure on concessionary fares and support to operators through local authorities only (Wales: no operator-side series and no Welsh Government grants outside the outturn), and the NITHC accounts' Public Service Obligation plus concessionary compensation as one bus-plus-rail cell excluding GBP 53.2m of other revenue funding (Northern Ireland). The legs are bound on their own terms; they are not a UK total under another name." + } + ] + }, + "obr.fuel_duties_cars": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000004", + "name": "obr.fuel_duties_cars", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 6299365751.358824, + "resolved_value": 14400000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_61b52be8ce7d4fc692817ba9" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_de6554fe8ab7b481035a432a" + } + ] + }, + "orr.rail_government_support": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000005", + "name": "orr.rail_government_support", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 5890960774.765152, + "resolved_value": 21621100549.34064, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_34a10615174b9297afe221b7" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b16b9b3f2329455f907f9ccc" + } + ] + }, + "ons.household_energy_expenditure": { + "status": "signed_excluded", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000006", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000006", - "resolved_period": 2025, - "resolved_value": 11545870966.728456, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f15225d0bcd17c6de4da7274" - }, + "name": "ons.household_energy_expenditure", + "status": "signed_excluded", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, + "signed_rationale": "ONS Consumer Trends COICOP 04.5 (electricity, gas and other fuels) carries liquid and solid fuels the frame does not model; chronicle #271 (chronicle#270) published the 04.5.1 electricity and 04.5.2 gas sub-classes, which ons.household_electricity_expenditure and ons.household_gas_expenditure bind per fuel on the frame's own columns. The total row is retained in the contract for registry parity and signed out here (microcosm#890 F1)." + } + ] + }, + "ons.household_electricity_expenditure": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000007", + "name": "ons.household_electricity_expenditure", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 32519714615.602127, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_1c9e621227b5e9e0de086a29" - }, + "resolved_value": 26522000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_69cd660b943ae8f21761f76a" + } + ] + }, + "ons.household_gas_expenditure": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000008", + "name": "ons.household_gas_expenditure", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 25606804690.69088, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e292074b43a3aaf4dbd7700e" - }, + "resolved_value": 15339000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b56be49c552300f6c02fc559" + } + ] + }, + "scotgov.bus.passenger_revenue": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@E12000009", + "name": "scotgov.bus.passenger_revenue", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, - "geography_level": "region", - "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 10341263627.509504, + "resolved_value": 391000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c7cfe6f18b190daed3153cfc" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_c4269bb83534f1e46f5801c1" + } + ] + }, + "scotgov.bus.government_support": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@W92000004", + "name": "scotgov.bus.government_support", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 2358632410.6946497, + "resolved_value": 499000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6cf6ec1d6cf7a4545c25ccb3" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ceb60fd41d0f5587be94c234" + } + ] + }, + "welshgov.bus.public_support": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@S92000003", + "name": "welshgov.bus.public_support", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 5680201325.83493, + "resolved_value": 131489970.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_4af3f233994240b66f222933" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_a10fcfec7cb458fa0c8c7f10" + } + ] + }, + "dfi_ni.bus.passenger_receipts": { + "status": "active", + "candidates": [ { - "name": "hmrc.cgt.gains_by_region@N92000002", + "name": "dfi_ni.bus.passenger_receipts", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 1757265449.747086, + "resolved_value": 150082817.48999995, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_8b23977ac0a2db5257dc6bfe" + "resolved_fact_key": "ledger_aggregate_fact_v2_96f72989614e0c5faaeeabbb" } ] }, - "hmrc.cgt.taxpayers_by_gain_band": { + "nithc.public_transport_support": { "status": "active", "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_0", - "status": "signed_excluded", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "signed_row": { - "dimension": "cgt_gain_band", - "value": "gain_0_to_2999" - }, - "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." - }, - { - "name": "hmrc/cgt_taxpayers_band_1000000", + "name": "nithc.public_transport_support", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 4, + "matched_fact_count_at_or_before_period": 4, "resolved_period": 2025, - "resolved_value": 9000.0, + "resolved_value": 111700000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6a760ffb56140426b69a5269" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_be8eb7011b6f65fa65d52fcb" + } + ] + }, + "dwp.uc.households_lcwra_element": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_100000", + "name": "dwp.uc.households_lcwra_element", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 61000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_9abad7ce7e36bcbf61e93db0" - }, + "resolved_value": 2272425.1666666665, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f59149c4c514e1acffb728a8" + } + ] + }, + "dwp.uc.households_carer_element": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_10000", + "name": "dwp.uc.households_carer_element", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 26000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2393740ba1c11b1a31e54e75" - }, + "resolved_value": 1078514.5, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_d56ddfa58d7ebb3ff0178b0a" + } + ] + }, + "dwp.uc.households_housing_element": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_12300", + "name": "dwp.uc.households_housing_element", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 97000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c5a351873a7b2c4cc4150711" - }, + "resolved_value": 4037650.3333333335, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_04b7ec6d195e6682f0421672" + } + ] + }, + "dwp.uc.households_housing_element_social_rented": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_2000000", + "name": "dwp.uc.households_housing_element_social_rented", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 5000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7a32f131c687a8bed9ec747a" - }, + "resolved_value": 2354587.5833333335, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_109598f6aaa42fe1387d30d1" + } + ] + }, + "dwp.uc.households_housing_element_private_rented": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_250000", + "name": "dwp.uc.households_housing_element_private_rented", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 25000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_9df6b0435f02114bbff8b83e" - }, + "resolved_value": 1570545.4166666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7a31b88dfcd4b3d0c758a1c3" + } + ] + }, + "dwp.uc.households_childcare_element": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_25000", + "name": "dwp.uc.households_childcare_element", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 98000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dbb814e164ce932da9f110e3" - }, + "resolved_value": 178666.66666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_0c1aa0cc56d86c50d6b2560a" + } + ] + }, + "dwp.uc.households_with_deduction": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_3000", + "name": "dwp.uc.households_with_deduction", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_in_source_window": 10, "resolved_period": 2025, - "resolved_value": 73000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_445cdec889b5a04a38bfc529" - }, + "resolved_value": 3130000.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7bfdb41a462c417535602d2" + } + ] + }, + "obr.universal_credit": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_5000000", + "name": "obr.universal_credit", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 14, + "matched_fact_count_at_or_before_period": 4, "resolved_period": 2025, - "resolved_value": 3000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_185d64390d180e168f174c93" - }, + "resolved_value": 79286349139.54411, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" + } + ] + }, + "dwp.hb.households": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_500000", + "name": "dwp.hb.households", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 16000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff1311e347cb11ab13a55da8" - }, + "resolved_value": 1685702.9166666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f2ecf4d38ef4dfc796336538" + } + ] + }, + "dwp.hb.households_social_rented": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_50000", + "name": "dwp.hb.households_social_rented", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 78000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_16303d73f7eadbadac68edc5" - }, + "resolved_value": 1381089.75, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_40b45c74a40b8d085a8c28e2" + } + ] + }, + "dwp.hb.households_private_rented": { + "status": "active", + "candidates": [ { - "name": "hmrc/cgt_taxpayers_band_6000", + "name": "dwp.hb.households_private_rented", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 57000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2f1e03f344a1e1de11bf0fe3" + "resolved_value": 304422.6666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_02281858b7b0d71477e429f3" } ] }, - "hmrc.cgt.gains_by_gain_band": { + "dwp.benefit_cap.capped_households_up_to_100": { "status": "active", "candidates": [ { - "name": "hmrc/capital_gains_band_0", - "status": "signed_excluded", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "signed_row": { - "dimension": "cgt_gain_band", - "value": "gain_0_to_2999" - }, - "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." - }, - { - "name": "hmrc/capital_gains_band_1000000", + "name": "dwp.benefit_cap.capped_households_up_to_100", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12806000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d4ad617897f228660a6a6be3" - }, + "resolved_value": 38402.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_220b82ab05bec494e6dc9fe9" + } + ] + }, + "dwp.benefit_cap.capped_households_100_01_to_200": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_100000", + "name": "dwp.benefit_cap.capped_households_100_01_to_200", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9487000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ed181e27011def0336c6cd99" - }, + "resolved_value": 24274.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_4a9e2cc181aee62e1eccd188" + } + ] + }, + "dwp.benefit_cap.capped_households_200_01_to_300": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_10000", + "name": "dwp.benefit_cap.capped_households_200_01_to_300", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 289000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_0ce43b4d53bb602f1b9fb49a" - }, + "resolved_value": 16240.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_5ae8289242eabcffab23f32f" + } + ] + }, + "dwp.benefit_cap.capped_households_300_01_to_400": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_12300", + "name": "dwp.benefit_cap.capped_households_300_01_to_400", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1747000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_52d8b43cd07113d29860cd06" - }, + "resolved_value": 10562.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_a503d4e938aaf386720b96c4" + } + ] + }, + "dwp.benefit_cap.capped_households_400_01_to_500": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_2000000", + "name": "dwp.benefit_cap.capped_households_400_01_to_500", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16477000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_36a58e75b04a937aa837b211" - }, + "resolved_value": 7813.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_df764409769b2078c69ff113" + } + ] + }, + "dwp.benefit_cap.capped_households_500_01_to_600": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_250000", + "name": "dwp.benefit_cap.capped_households_500_01_to_600", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8820000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e79c0dd87ea41c5469aa88af" - }, + "resolved_value": 4431.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_3d0e936b240ba62209777ee3" + } + ] + }, + "dwp.benefit_cap.capped_households_600_01_to_700": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_25000", + "name": "dwp.benefit_cap.capped_households_600_01_to_700", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3516000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_12a05bb18f0245343b24c882" - }, + "resolved_value": 3116.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_1d68398dd88958a8700dcfac" + } + ] + }, + "dwp.benefit_cap.capped_households_700_01_to_800": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_3000", + "name": "dwp.benefit_cap.capped_households_700_01_to_800", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 311000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_68d13fca859e018be0915149" - }, + "resolved_value": 1902.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_999288b0fa67d7f657810a11" + } + ] + }, + "dwp.benefit_cap.capped_households_800_01_to_900": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_5000000", + "name": "dwp.benefit_cap.capped_households_800_01_to_900", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 48474000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e86658beb663c322dfe3f311" - }, + "resolved_value": 1328.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_b7a2d0cec131abfd0cb81ba0" + } + ] + }, + "dwp.benefit_cap.capped_households_900_01_to_1000": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_500000", + "name": "dwp.benefit_cap.capped_households_900_01_to_1000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11372000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bcee60127caf8ba271530f73" - }, + "resolved_value": 824.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_80c8fa82f3e07357e677ae93" + } + ] + }, + "dwp.benefit_cap.capped_households_1000_01_to_1100": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_50000", + "name": "dwp.benefit_cap.capped_households_1000_01_to_1100", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5510000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6854e6a3ad1abc041042f35d" - }, + "resolved_value": 497.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_cf55cee33404d2283800b2b5" + } + ] + }, + "dwp.benefit_cap.capped_households_1100_01_to_1200": { + "status": "active", + "candidates": [ { - "name": "hmrc/capital_gains_band_6000", + "name": "dwp.benefit_cap.capped_households_1100_01_to_1200", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 448000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f808792afed121cadff6f396" + "resolved_value": 380.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_6f836a33391f4352151bd27f" } ] }, - "hmrc.cgt.residential_property_taxpayers": { + "dwp.benefit_cap.capped_households_1200_01_to_1300": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.residential_property_taxpayers.ty2024", + "name": "dwp.benefit_cap.capped_households_1200_01_to_1300", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 202630.0578034682, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a26f1261bd153727b83045de" + "resolved_value": 239.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_ad08714cf39be9ccf0450cf2" } ] }, - "hmrc.cgt.residential_property_gains": { + "dwp.benefit_cap.capped_households_1300_01_and_above": { "status": "active", "candidates": [ { - "name": "hmrc.cgt.residential_property_gains.ty2024", + "name": "dwp.benefit_cap.capped_households_1300_01_and_above", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12242481474.688189, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_1f8003c937764e4184da3f24" + "resolved_value": 627.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_a3fee6cdec1b46a15a3b1434" } ] } @@ -14512,12 +13122,6 @@ "active_reference_count": 100, "signed_rationale": "MHCLG council taxbase (England), Welsh Government CT1 (Wales) and Scottish Government CTAXBASE (Scotland) council-tax stock bands are declared as explicit target rows per band plus total (England and Scotland A-H, Wales A-I). The Welsh and Scottish rows resolve with their country-level geography and band pin; the English rows fan out over the nine English regions of the region tier (microcosm#905), each cell composed as the linear combination of the billing-authority facts the crosswalk places in that region (microcosm#929)." }, - { - "family": "hmrc_cgt", - "status": "active_with_row_level_signed_exclusions", - "active_reference_count": 74, - "signed_rationale": "The FY2024-25 individual CGT observations fan out three ways (microcosm#725, #467): Table 6 age bands as dimension rows (the 0-15 band and the all-ages total are signed out row by row), Table 5 country/region cells over the twelve-area region tier restated on the individuals basis by the Table 1 share through the scaled_by_ratio operation, and Table 2.1a size-of-gain bands under the incumbent banded names (the 0-2,999 band below the 2024 annual exempt amount is signed out). Chronicle's Table 2.1a package emits taxpayers and gains only, although the published sheet also carries an amounts-of-tax column, so liability binds nationally and by age band; a liability-by-size-of-gain family becomes possible once Chronicle emits that column." - }, { "family": "ons_population", "status": "active_region_tier_fanout", @@ -14537,41 +13141,6 @@ "target_id": "ons.population.scotland_households_3plus_children", "status": "signed_excluded", "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." - }, - { - "family": "hmrc_cgt", - "target_id": "hmrc.cgt.gains_by_age_band", - "row": "hmrc.cgt.gains_by_age_band.age_0_to_15", - "status": "signed_excluded", - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "family": "hmrc_cgt", - "target_id": "hmrc.cgt.gains_by_gain_band", - "row": "hmrc/capital_gains_band_0", - "status": "signed_excluded", - "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." - }, - { - "family": "hmrc_cgt", - "target_id": "hmrc.cgt.tax_by_age_band", - "row": "hmrc.cgt.tax_by_age_band.age_0_to_15", - "status": "signed_excluded", - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "family": "hmrc_cgt", - "target_id": "hmrc.cgt.taxpayers_by_age_band", - "row": "hmrc.cgt.taxpayers_by_age_band.age_0_to_15", - "status": "signed_excluded", - "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." - }, - { - "family": "hmrc_cgt", - "target_id": "hmrc.cgt.taxpayers_by_gain_band", - "row": "hmrc/cgt_taxpayers_band_0", - "status": "signed_excluded", - "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." } ], "multi_fact_rationales": [] diff --git a/packages/microcosm-build/src/microcosm/build/uk/uk_local_target_census.json b/packages/microcosm-build/src/microcosm/build/uk/uk_local_target_census.json index 46d467232..d2829fb49 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/uk_local_target_census.json +++ b/packages/microcosm-build/src/microcosm/build/uk/uk_local_target_census.json @@ -565,11 +565,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "Unbanded area statistics in the pinned Ledger fact feed supply the local HMRC count targets directly and the amount targets via the signed count_x_mean construction. The feed publishes SPI target count/mean measures for 650/650 constituencies except self_employment_income_mean at E14001416 (so that one amount row is signed deferred), and for 359/361 crosswalk local authorities; E06000027 has only median SPI measures and E06000053 has no SPI local-authority target-measure rows. This remains a different surface from the 208 banded Total Income facts held fenced by the national adjudication.", @@ -588,11 +588,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries the PCON24 constituency population age specs for all 650 constituencies across the ONS, NRS, and NISRA publisher legs. Mid-year estimates cover the total usual-resident population \u2014 see the population_universe_private_households adjudication.", @@ -611,11 +611,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries local-authority population age specs for all 361 crosswalk local authorities. Covers the total usual-resident population \u2014 see the population_universe_private_households adjudication.", @@ -635,11 +635,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries the compiled household cells.", @@ -659,11 +659,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries the compiled household cells; the source specification defines HouseholdCount as occupied households.", @@ -683,11 +683,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries the compiled household cells.", @@ -707,11 +707,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries DWP Stat-Xplore UC household facts for 632/650 constituencies and 350/361 local authorities, plus the four constituency child-bucket specs. DWP UC official statistics in this feed cover Great Britain; the 18 Northern Ireland constituencies and 11 Northern Ireland local authorities are signed deferred. DWP counts UC claim households \u2014 see the uc_unit_vs_household_grain adjudication.", @@ -730,11 +730,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "Model-based estimates built from the Family Resources Survey \u2014 see the frs_model_based_target_circularity adjudication. The BHC and AHC measures are independently modelled and not directly comparable \u2014 see the ons_bhc_ahc_noncomparable adjudication. MSOA-to-local-authority aggregation is signed deferred for this run; England and Wales only.", @@ -756,11 +756,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned Ledger fact feed carries tenure specs for all 361 crosswalk local authorities across ONS Census 2021, NRS Census 2022, and NISRA Census 2021 publisher legs. Private-rent and social-rent tenure rows are additive over publisher-native subclasses and compile through the signed sum operation.", @@ -779,11 +779,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "PIPR publishes average rent price levels, not additive rent totals; a bound cell composes the level into a total (see the signed rationale). Of the 361 local-authority cells, 314 bind for the 2025 compile and 47 remain signed deferred: four English cells have no matching LA id, 32 Scottish cells are represented only at BRMA grain without a signed translation, and 11 Northern Ireland cells are absent.", @@ -804,11 +804,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned feed record-set specs uk.local_geography.council_tax.england_ctb.line_07_chargeable_dwellings_adjusted_for_disabled_relief.v1, line_11_second_homes.v1 and line_15_empty_dwellings.v1 supply the 296 English billing authorities by band A-, A-H at the October 2025 count. Each cell binds line 7 minus line 11 minus line 15 (band A adds line 7's A- column): the dwellings charged as someone's sole or main residence, the universe a household frame carries. Bands A-G bind 294 authorities after E06000053 and E09000001 are support-floor excluded; the 296-cell band H family stays signed deferred on spine support (microcosm#762 A14). Barnsley and Sheffield bind through the crosswalk's declared aliases of their April 2025 codes. The family is scoped to the 296 English authorities: Wales and Scotland bind their own returns below and Northern Ireland levies domestic rates.", @@ -827,11 +827,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned feed record-set specs uk.local_geography.council_tax.wales_ct1.a1_all_chargeable_dwellings.v1, h7_total_chargeable_empty_properties.v1 and h8_total_chargeable_second_homes.v1 supply the 22 Welsh authorities by band A-I per financial year. Each cell binds a1 minus h7 minus h8 on the 2025-26 row (the taxbase set for that year, counted on the 31 October 2024 list, one count-year behind England and Scotland by ruling of 2026-09-15); all 198 cells bind, band I included.", @@ -850,11 +850,11 @@ "ledger_fact_pin": { "artifact": ".codex-work/consumer_facts_uk.jsonl", "build": "build-bundle --suite uk -> build-consumer-artifact", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", "manifest": ".codex-work/consumer_facts_uk_manifest.json", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "source_repo": "PolicyEngine/chronicle" }, "notes": "The pinned feed record-set spec uk.local_geography.council_tax_stock.scotland_ctaxbase_chargeable_dwellings.by_council_area.v1 supplies the 32 councils by band A-H, the concept the scotgov.council_tax_stock country rows already bind; 255 cells bind and Shetland band H is signed deferred (no band-H clone at K=15). Chargeable dwellings run about 1 % above the household frame nationally, the residual the universe fence records.", diff --git a/packages/microcosm-build/tests/test_country_spec.py b/packages/microcosm-build/tests/test_country_spec.py index 873bf0026..8a235a407 100644 --- a/packages/microcosm-build/tests/test_country_spec.py +++ b/packages/microcosm-build/tests/test_country_spec.py @@ -988,6 +988,9 @@ def test_spi_spine_adds_no_country_package_resources(self) -> None: "devolved_bus_finance.json", "orr_rail_facts.json", "ons_household_expenditure_facts.json", + "dft_bus_journeys.json", + "nts_trip_rates.json", + "nts_car_availability.json", ) def test_uk_source_manifest_loads_thirty_stages(self) -> None: @@ -1096,6 +1099,9 @@ def test_uk_package_loads(self) -> None: "devolved_bus_finance.json", "orr_rail_facts.json", "ons_household_expenditure_facts.json", + "dft_bus_journeys.json", + "nts_trip_rates.json", + "nts_car_availability.json", ) def test_uk_target_references_accept_regenerated_contract_fields(self) -> None: diff --git a/packages/microcosm-build/tests/test_uk_chronicle_feed.py b/packages/microcosm-build/tests/test_uk_chronicle_feed.py index 771ff4486..75aa3392c 100644 --- a/packages/microcosm-build/tests/test_uk_chronicle_feed.py +++ b/packages/microcosm-build/tests/test_uk_chronicle_feed.py @@ -15,14 +15,14 @@ def test_national_feed_records_the_complete_merged_source_artifact(): pin = load_uk_chronicle_feed() resource = files("microcosm.build.uk").joinpath("chronicle_feed.json") raw = resource.read_bytes() - assert pin.source_commit == "c5e5bf8aa84960c1a200ee47303b19c953092d0f" + assert pin.source_commit == "78466057401af48f9a53da41b87295241e4af1ba" assert pin.source_repo == "PolicyEngine/chronicle" - assert pin.fact_row_count == 276205 + assert pin.fact_row_count == 277183 assert pin.facts_sha256 == ( - "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d" + "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a" ) assert pin.manifest_sha256 == ( - "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" ) assert pin.artifact_schema_version == "policyengine_ledger.consumer_artifact.v2" assert pin.consumer_fact_schema_versions == ("chronicle.consumer_fact.v3",) From db2f85b6e3c20d99dc39d1cb774c5799c4ed7276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 15:59:28 +0100 Subject: [PATCH 02/19] Write the calibration's compiled system and weights before the battery, and read the per-target weight-stretch anatomy from them (#930 C1) A national calibration attempt the terminal battery blocks wrote no staging H5 and no weight vector, so the per-target anatomy (how much of a target's fitted mass sits on households the solver stretched) could not be read: the #890 acceptance line on England bus fares was never re-measured (receipts Part N). The seam now writes the solve's CSR matrix, row names, target vector, design and final household weights and household ids beside the diagnostics, before the battery runs, as non-release sidecars with a manifest of digests; the H5 posture is unchanged. tools/diagnose_uk_target_support.py decomposes any compiled row from them: target, design and final aggregates, carrier count, top-1/top-5 shares, the carrier weight-ratio distribution, the share of final mass on households stretched beyond declared multiples of design (3x and 5x by default) beside the frame-wide share above the same multiple, and the near-cap fraction; the recomputed final estimates are verified against the attempt's diagnostics so another attempt's sidecars are refused. Ported from the US target-support tool's decomposition with the stretched-mass buckets added. Co-Authored-By: Claude Fable 5.1 --- .../930-target-support-anatomy.added.md | 1 + .../build/uk_runtime/calibration_run.py | 21 + .../build/uk_runtime/target_support.py | 446 ++++++++++++++++++ .../tests/test_uk_target_support.py | 218 +++++++++ tools/diagnose_uk_target_support.py | 141 ++++++ 5 files changed, 827 insertions(+) create mode 100644 changelog.d/930-target-support-anatomy.added.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/target_support.py create mode 100644 packages/microcosm-build/tests/test_uk_target_support.py create mode 100644 tools/diagnose_uk_target_support.py diff --git a/changelog.d/930-target-support-anatomy.added.md b/changelog.d/930-target-support-anatomy.added.md new file mode 100644 index 000000000..68dcf1f0c --- /dev/null +++ b/changelog.d/930-target-support-anatomy.added.md @@ -0,0 +1 @@ +A UK national calibration attempt now writes its compiled constraint system and both household weight vectors beside the diagnostics before the terminal battery runs (`target_support_matrix.npz`, `target_support_vectors.npz`, `target_support_manifest.json`; `uk_runtime/target_support.py`), so an attempt the battery blocks keeps its per-target weight-stretch anatomy readable; the staging H5 posture is unchanged and the sidecars are non-release evidence. `tools/diagnose_uk_target_support.py` decomposes any compiled target from them: target, design and final aggregates, carrier count, top-carrier concentration, the carrier weight-ratio distribution, the share of the target's final mass on households stretched beyond declared multiples of their design weight (3x and 5x by default, each beside the frame-wide share above the same multiple) and the near-cap fraction, with the recomputed final estimates verified against the attempt's diagnostics. This is the instrument behind microcosm#890's acceptance line (the share of England bus-fare mass on households stretched more than 3x) and microcosm#930's measurement. 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 2e591a690..a39185193 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 @@ -68,6 +68,9 @@ uk_time_period, write_uk_national_frame, ) +from microcosm.build.uk_runtime.target_support import ( + write_uk_target_support_sidecars, +) from microcosm.calibrate import TargetRegistry from microcosm.frame import Frame @@ -622,6 +625,24 @@ def _run_uk_calibration_attempt( target_count=len(stage.diagnostics), ) + # The solve's compiled system and both weight vectors are written beside + # the diagnostics before the terminal battery runs, so an attempt the + # battery blocks still leaves the per-target weight-stretch anatomy + # readable (tools/diagnose_uk_target_support.py; microcosm#930, the + # #890 acceptance line). Non-release sidecars: the staging H5 posture is + # unchanged, nothing here is a shippable artifact. + _notify_run_event(event_callback, "target_support_sidecars", "started") + sidecars = write_uk_target_support_sidecars( + stage.solve_result, paths.diagnostics_json.parent + ) + append_phase(state, "target_support_sidecars_written") + _notify_run_event( + event_callback, + "target_support_sidecars", + "completed", + files=sorted(str(path.name) for path in sidecars.values()), + ) + _notify_run_event(event_callback, "release_check_evaluation", "started") gate_report = _run_calibration_gate_battery( calibrated, diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/target_support.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/target_support.py new file mode 100644 index 000000000..a83d05943 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/target_support.py @@ -0,0 +1,446 @@ +"""Per-target weight-stretch anatomy for a UK national calibration attempt. + +A national solve compiles one sparse row per target over the household weight +vector (``A @ w`` estimates each target). The staging H5 that carries the final +weights is written only after the terminal battery passes, so an attempt the +battery blocks used to leave nothing from which the per-target anatomy (how +much of a target's fitted mass sits on households the solver stretched) could +be read. :func:`write_uk_target_support_sidecars` writes the compiled system +and both weight vectors beside the diagnostics *before* the battery runs; +:func:`target_support_anatomy` reads them back and decomposes any target into +its carriers, the share of its final aggregate on households stretched beyond +declared ratios of their design weight, and the concentration on its top +carriers. This is the instrument behind microcosm#890's acceptance line (the +share of England bus-fare mass on households stretched more than 3x) and +microcosm#930's measurement. + +The sidecars are non-release evidence: nothing here is a shippable artifact, +and the staging H5 posture is unchanged. +""" + +from __future__ import annotations + +import hashlib +import json +from collections.abc import Iterable, Mapping, Sequence +from dataclasses import dataclass +from pathlib import Path +from typing import Any + +import numpy as np +from scipy import sparse + +#: The compiled constraint matrix ``A`` (targets x households), CSR. +TARGET_SUPPORT_MATRIX_FILE = "target_support_matrix.npz" +#: Row names, target vector, design (initial) and final weights, household ids. +TARGET_SUPPORT_VECTORS_FILE = "target_support_vectors.npz" +#: Shapes and digests of the two sidecars, so a reader can refuse a mismatch. +TARGET_SUPPORT_MANIFEST_FILE = "target_support_manifest.json" +#: Default weight-ratio thresholds for the stretched-mass buckets. +DEFAULT_STRETCH_THRESHOLDS: tuple[float, ...] = (3.0, 5.0) +#: Carriers whose ratio exceeds this fraction of the realised maximum ratio +#: are reported as pinned near the solver's cap. +NEAR_CAP_FRACTION = 0.9 + + +class TargetSupportError(RuntimeError): + """Raised when the sidecars are inconsistent or a target is unknown.""" + + +def _weight_values(weights: object) -> np.ndarray: + values = getattr(weights, "values", weights) + array = np.asarray(values, dtype=float) + if array.ndim != 1: + raise TargetSupportError(f"weights must be one-dimensional, got {array.shape}.") + return array + + +def _sha256(path: Path) -> str: + digest = hashlib.sha256() + with path.open("rb") as handle: + for chunk in iter(lambda: handle.read(1 << 20), b""): + digest.update(chunk) + return digest.hexdigest() + + +@dataclass(frozen=True) +class TargetSupportSidecars: + """The compiled system and weights of one calibration attempt.""" + + matrix: sparse.csr_array + names: tuple[str, ...] + target_vector: np.ndarray + design_weights: np.ndarray + final_weights: np.ndarray + household_ids: np.ndarray | None + + def __post_init__(self) -> None: + n_rows, n_cols = self.matrix.shape + if not (len(self.names) == len(self.target_vector) == n_rows): + raise TargetSupportError( + f"target rows disagree: matrix {n_rows}, names {len(self.names)}, " + f"targets {len(self.target_vector)}." + ) + if not (len(self.design_weights) == len(self.final_weights) == n_cols): + raise TargetSupportError( + f"weight vectors disagree with the matrix: matrix {n_cols} columns, " + f"design {len(self.design_weights)}, final {len(self.final_weights)}." + ) + if self.household_ids is not None and len(self.household_ids) != n_cols: + raise TargetSupportError( + f"household ids ({len(self.household_ids)}) do not match the " + f"matrix columns ({n_cols})." + ) + + def row(self, name: str) -> int: + try: + return self.names.index(name) + except ValueError: + without_period = [n for n in self.names if n.split("@", 1)[0] == name] + if len(without_period) == 1: + return self.names.index(without_period[0]) + raise TargetSupportError( + f"target {name!r} is not a compiled row of this attempt " + f"({len(self.names)} rows)." + ) from None + + +def write_uk_target_support_sidecars( + result: Any, directory: str | Path +) -> dict[str, Path]: + """Write the solve's compiled system and weight vectors beside the diagnostics. + + ``result`` is a :class:`microcosm.calibrate.CalibrationResult`: its + ``problem`` carries the CSR matrix, the row names and the target vector; + ``initial_weights`` and ``weights`` are the design and final household + weight vectors. Household ids are taken from the calibrated frame's + household table when it carries one. + """ + + directory = Path(directory) + directory.mkdir(parents=True, exist_ok=True) + problem = result.problem + matrix = sparse.csr_array(problem.matrix) + names = np.asarray([str(name) for name in problem.names], dtype=object) + target_vector = np.asarray(problem.target_vector, dtype=float) + design = _weight_values(result.initial_weights) + final = _weight_values(result.weights) + household_ids: np.ndarray | None = None + frame = getattr(result, "frame", None) + weight_entity = str(getattr(result, "weight_entity", "household")) + if frame is not None: + try: + table = frame.table(weight_entity) + except Exception: # pragma: no cover - a frame without the entity + table = None + id_column = f"{weight_entity}_id" + if table is not None and id_column in table: + household_ids = np.asarray(table[id_column].to_numpy()) + sidecars = TargetSupportSidecars( + matrix=matrix, + names=tuple(str(n) for n in names), + target_vector=target_vector, + design_weights=design, + final_weights=final, + household_ids=household_ids, + ) + matrix_path = directory / TARGET_SUPPORT_MATRIX_FILE + vectors_path = directory / TARGET_SUPPORT_VECTORS_FILE + manifest_path = directory / TARGET_SUPPORT_MANIFEST_FILE + sparse.save_npz(matrix_path, sidecars.matrix, compressed=True) + vectors: dict[str, np.ndarray] = { + "names": names, + "target_vector": target_vector, + "design_weights": design, + "final_weights": final, + } + if household_ids is not None: + vectors["household_ids"] = household_ids + np.savez_compressed(vectors_path, **vectors) + manifest = { + "kind": "uk_target_support_sidecars", + "version": 1, + "weight_entity": weight_entity, + "targets": int(matrix.shape[0]), + "records": int(matrix.shape[1]), + "nonzeros": int(matrix.nnz), + "household_ids": household_ids is not None, + "files": { + TARGET_SUPPORT_MATRIX_FILE: _sha256(matrix_path), + TARGET_SUPPORT_VECTORS_FILE: _sha256(vectors_path), + }, + "note": ( + "Non-release evidence written before the terminal battery so a " + "blocked attempt keeps its per-target weight-stretch anatomy " + "(tools/diagnose_uk_target_support.py)." + ), + } + manifest_path.write_text(json.dumps(manifest, indent=2) + "\n") + return { + "matrix": matrix_path, + "vectors": vectors_path, + "manifest": manifest_path, + } + + +def load_uk_target_support_sidecars(directory: str | Path) -> TargetSupportSidecars: + """Read the sidecars of one attempt, refusing a digest or shape mismatch.""" + + directory = Path(directory) + manifest_path = directory / TARGET_SUPPORT_MANIFEST_FILE + matrix_path = directory / TARGET_SUPPORT_MATRIX_FILE + vectors_path = directory / TARGET_SUPPORT_VECTORS_FILE + for path in (manifest_path, matrix_path, vectors_path): + if not path.is_file(): + raise TargetSupportError(f"missing target-support sidecar {path}.") + manifest = json.loads(manifest_path.read_text()) + if manifest.get("kind") != "uk_target_support_sidecars": + raise TargetSupportError(f"{manifest_path}: not a target-support manifest.") + for name, path in ( + (TARGET_SUPPORT_MATRIX_FILE, matrix_path), + (TARGET_SUPPORT_VECTORS_FILE, vectors_path), + ): + expected = str(manifest.get("files", {}).get(name, "")) + actual = _sha256(path) + if expected != actual: + raise TargetSupportError( + f"{path.name}: sha256 {actual} differs from the manifest's {expected}." + ) + matrix = sparse.csr_array(sparse.load_npz(matrix_path)) + with np.load(vectors_path, allow_pickle=True) as vectors: + names = tuple(str(n) for n in vectors["names"]) + target_vector = np.asarray(vectors["target_vector"], dtype=float) + design = np.asarray(vectors["design_weights"], dtype=float) + final = np.asarray(vectors["final_weights"], dtype=float) + household_ids = ( + np.asarray(vectors["household_ids"]) + if "household_ids" in vectors.files + else None + ) + sidecars = TargetSupportSidecars( + matrix=matrix, + names=names, + target_vector=target_vector, + design_weights=design, + final_weights=final, + household_ids=household_ids, + ) + if (int(manifest.get("targets", -1)), int(manifest.get("records", -1))) != ( + matrix.shape[0], + matrix.shape[1], + ): + raise TargetSupportError( + f"{manifest_path}: declared shape " + f"({manifest.get('targets')}, {manifest.get('records')}) differs from " + f"the matrix {matrix.shape}." + ) + return sidecars + + +def realised_max_weight_ratio(sidecars: TargetSupportSidecars) -> float | None: + """The solve's realised maximum final/design weight ratio (positive design).""" + + positive = sidecars.design_weights > 0.0 + if not positive.any(): + return None + ratios = sidecars.final_weights[positive] / sidecars.design_weights[positive] + return float(ratios.max()) + + +def target_support_anatomy( + sidecars: TargetSupportSidecars, + name: str, + *, + stretch_thresholds: Sequence[float] = DEFAULT_STRETCH_THRESHOLDS, + top: int = 10, + near_cap_ratio: float | None = None, +) -> dict[str, Any]: + """Decompose one compiled target into its carriers and stretched mass. + + A carrier is a household with a nonzero compiled value on the row. The + final aggregate is ``sum(value * final_weight)``; for each threshold ``k`` + the report gives the share of that aggregate carried by households whose + final weight exceeds ``k`` times their design weight (``stretched_mass``) + and the share of carriers so stretched (``stretched_carriers``), beside the + frame-wide share of *all* weight above ``k`` times design, which is the + baseline the target's share is read against. Carriers are ranked by + absolute weighted contribution so signed rows report their dominant + carriers. + """ + + if top < 1: + raise ValueError("top must be positive.") + thresholds = tuple(float(t) for t in stretch_thresholds) + if any(t <= 0 for t in thresholds): + raise ValueError("stretch thresholds must be positive.") + row = sidecars.row(name) + compiled = np.asarray(sidecars.matrix[[row], :].toarray()).ravel() + design = sidecars.design_weights + final = sidecars.final_weights + target_value = float(sidecars.target_vector[row]) + contributions = compiled * final + design_contributions = compiled * design + carrier_mask = compiled != 0.0 + carrier_indices = np.flatnonzero(carrier_mask) + ranked = carrier_indices[ + np.argsort(-np.abs(contributions[carrier_indices]), kind="stable") + ] + total = float(contributions.sum()) + design_total = float(design_contributions.sum()) + with np.errstate(divide="ignore", invalid="ignore"): + ratios = np.where(design > 0.0, final / design, np.nan) + carrier_ratios = ratios[carrier_mask] + finite_carrier_ratios = carrier_ratios[np.isfinite(carrier_ratios)] + + def _share(count: int) -> float | None: + if total == 0.0: + return None + return float(contributions[ranked[:count]].sum() / total) + + frame_total_weight = float(final.sum()) + stretched: dict[str, dict[str, float | None]] = {} + for threshold in thresholds: + key = f"{threshold:g}x" + above = np.isfinite(ratios) & (ratios > threshold) + mass = ( + float(contributions[carrier_mask & above].sum() / total) + if total != 0.0 + else None + ) + carriers_above = ( + float((carrier_mask & above).sum() / carrier_mask.sum()) + if carrier_mask.any() + else None + ) + frame_share = ( + float(final[above].sum() / frame_total_weight) + if frame_total_weight > 0.0 + else None + ) + stretched[key] = { + "threshold": threshold, + "stretched_mass": mass, + "stretched_carriers": carriers_above, + "frame_weight_share": frame_share, + } + carriers: list[dict[str, object]] = [] + for index in ranked[:top]: + entry: dict[str, object] = { + "record_index": int(index), + "compiled_value": float(compiled[index]), + "design_weight": float(design[index]), + "final_weight": float(final[index]), + "weight_ratio": float(ratios[index]) + if np.isfinite(ratios[index]) + else None, + "weighted_contribution": float(contributions[index]), + "contribution_share": ( + float(contributions[index] / total) if total != 0.0 else None + ), + } + if sidecars.household_ids is not None: + value = sidecars.household_ids[index] + entry["household_id"] = value.item() if hasattr(value, "item") else value + carriers.append(entry) + report: dict[str, Any] = { + "name": sidecars.names[row], + "target": target_value, + "design_estimate": design_total, + "final_estimate": total, + "design_relative_error": ( + design_total / target_value - 1.0 if target_value else None + ), + "final_relative_error": (total / target_value - 1.0 if target_value else None), + "carrier_count": int(carrier_mask.sum()), + "carriers_with_nonpositive_design_weight": int( + (design[carrier_mask] <= 0.0).sum() + ), + "top_1_share": _share(1), + "top_5_share": _share(5), + f"top_{top}_share": _share(top), + "carrier_weight_ratio": { + "mean": ( + float(finite_carrier_ratios.mean()) + if finite_carrier_ratios.size + else None + ), + "median": ( + float(np.median(finite_carrier_ratios)) + if finite_carrier_ratios.size + else None + ), + "p90": ( + float(np.quantile(finite_carrier_ratios, 0.9)) + if finite_carrier_ratios.size + else None + ), + "max": ( + float(finite_carrier_ratios.max()) + if finite_carrier_ratios.size + else None + ), + }, + "stretched": stretched, + "top_carriers": carriers, + } + if near_cap_ratio is not None and finite_carrier_ratios.size: + report["carrier_share_near_cap"] = float( + (finite_carrier_ratios > near_cap_ratio).mean() + ) + return report + + +def anatomy_for_targets( + sidecars: TargetSupportSidecars, + names: Iterable[str], + *, + stretch_thresholds: Sequence[float] = DEFAULT_STRETCH_THRESHOLDS, + top: int = 10, +) -> list[dict[str, Any]]: + """The anatomy of every named target, with the near-cap fraction resolved.""" + + max_ratio = realised_max_weight_ratio(sidecars) + near_cap = None if max_ratio is None else NEAR_CAP_FRACTION * max_ratio + return [ + target_support_anatomy( + sidecars, + name, + stretch_thresholds=stretch_thresholds, + top=top, + near_cap_ratio=near_cap, + ) + for name in names + ] + + +def verify_against_diagnostics( + reports: Sequence[Mapping[str, Any]], + diagnostics: Mapping[str, Any], + *, + rtol: float = 1e-9, + atol: float = 0.5, +) -> None: + """Refuse a sidecar whose recomputed final estimates differ from the diagnostics.""" + + recorded: dict[str, float] = {} + for row in diagnostics.get("targets", ()): + if not isinstance(row, Mapping): + continue + for key in ("name", "target_name"): + value = row.get(key) + if isinstance(value, str) and "final_estimate" in row: + recorded[value] = float(row["final_estimate"]) + for report in reports: + name = str(report["name"]) + candidates = [name, name.split("@", 1)[0]] + expected = next((recorded[c] for c in candidates if c in recorded), None) + if expected is None: + raise TargetSupportError( + f"{name}: the diagnostics carry no final_estimate for this row." + ) + actual = float(report["final_estimate"]) + if abs(actual - expected) > atol + rtol * abs(expected): + raise TargetSupportError( + f"{name}: recomputed final estimate {actual} differs from the " + f"diagnostics' {expected}; the sidecars are not this attempt's." + ) diff --git a/packages/microcosm-build/tests/test_uk_target_support.py b/packages/microcosm-build/tests/test_uk_target_support.py new file mode 100644 index 000000000..f6bec0bfc --- /dev/null +++ b/packages/microcosm-build/tests/test_uk_target_support.py @@ -0,0 +1,218 @@ +"""The target-support sidecars and the per-target weight-stretch anatomy.""" + +from __future__ import annotations + +import json +from pathlib import Path +from types import SimpleNamespace + +import numpy as np +import pandas as pd +import pytest +from scipy import sparse + +from microcosm.build.uk_runtime.target_support import ( + TARGET_SUPPORT_MANIFEST_FILE, + TARGET_SUPPORT_MATRIX_FILE, + TargetSupportError, + TargetSupportSidecars, + anatomy_for_targets, + load_uk_target_support_sidecars, + realised_max_weight_ratio, + target_support_anatomy, + verify_against_diagnostics, + write_uk_target_support_sidecars, +) + + +def _sidecars() -> TargetSupportSidecars: + # Six households; three compiled rows. Row "fares" is carried by four + # households, two of which the solver stretched (x4 and x6); row "flat" is + # carried by every household at one unit; row "signed" mixes signs. + matrix = sparse.csr_array( + np.array( + [ + [10.0, 20.0, 0.0, 5.0, 0.0, 15.0], + [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], + [3.0, -2.0, 0.0, 0.0, 0.0, 0.0], + ] + ) + ) + design = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 1.0]) + final = np.array([4.0, 1.0, 1.0, 6.0, 0.5, 1.0]) + return TargetSupportSidecars( + matrix=matrix, + names=("fares@2025", "flat@2025", "signed@2025"), + target_vector=np.array([100.0, 12.0, 1.0]), + design_weights=design, + final_weights=final, + household_ids=np.array([11, 12, 13, 14, 15, 16]), + ) + + +def test_anatomy_reports_stretched_mass_beside_the_frame_share() -> None: + sidecars = _sidecars() + report = target_support_anatomy(sidecars, "fares") + # Contributions at final weights: 40, 20, 0, 30, 0, 15 -> 105. + assert report["name"] == "fares@2025" + assert report["final_estimate"] == pytest.approx(105.0) + assert report["design_estimate"] == pytest.approx(50.0) + assert report["final_relative_error"] == pytest.approx(0.05) + assert report["design_relative_error"] == pytest.approx(-0.5) + assert report["carrier_count"] == 4 + # Ranked by absolute contribution: h11 (40), h14 (30), h12 (20), h16 (15). + assert report["top_1_share"] == pytest.approx(40 / 105) + assert report["top_5_share"] == pytest.approx(1.0) + assert [c["household_id"] for c in report["top_carriers"]] == [11, 14, 12, 16] + # Stretched beyond 3x: h11 (x4) and h14 (x6) carry 70 of 105; beyond 5x + # only h14 (30 of 105). Frame-wide, weight above 3x is 10 of 13.5. + three = report["stretched"]["3x"] + assert three["stretched_mass"] == pytest.approx(70 / 105) + assert three["stretched_carriers"] == pytest.approx(0.5) + assert three["frame_weight_share"] == pytest.approx(10 / 13.5) + five = report["stretched"]["5x"] + assert five["stretched_mass"] == pytest.approx(30 / 105) + assert five["stretched_carriers"] == pytest.approx(0.25) + assert five["frame_weight_share"] == pytest.approx(6 / 13.5) + ratio = report["carrier_weight_ratio"] + assert ratio["max"] == pytest.approx(6.0) + assert ratio["median"] == pytest.approx(2.5) + # A signed row ranks its dominant carrier by absolute contribution. + signed = target_support_anatomy(sidecars, "signed@2025", top=2) + assert signed["final_estimate"] == pytest.approx(3 * 4 - 2 * 1) + assert [c["household_id"] for c in signed["top_carriers"]] == [11, 12] + with pytest.raises(TargetSupportError, match="not a compiled row"): + target_support_anatomy(sidecars, "missing") + with pytest.raises(ValueError, match="positive"): + target_support_anatomy(sidecars, "fares", stretch_thresholds=(0.0,)) + + +def test_anatomy_for_targets_resolves_the_near_cap_fraction() -> None: + sidecars = _sidecars() + assert realised_max_weight_ratio(sidecars) == pytest.approx(6.0) + reports = anatomy_for_targets(sidecars, ["fares", "flat"], top=3) + assert [r["name"] for r in reports] == ["fares@2025", "flat@2025"] + # Near the cap: carriers above 0.9 x 6 = 5.4, i.e. h14 alone of four. + assert reports[0]["carrier_share_near_cap"] == pytest.approx(0.25) + assert reports[1]["carrier_count"] == 6 + assert "top_3_share" in reports[0] + + +def test_sidecars_round_trip_and_refuse_tampering(tmp_path: Path) -> None: + sidecars = _sidecars() + household = pd.DataFrame({"household_id": sidecars.household_ids}) + result = SimpleNamespace( + problem=SimpleNamespace( + matrix=sidecars.matrix, + names=sidecars.names, + target_vector=sidecars.target_vector, + ), + initial_weights=SimpleNamespace(values=sidecars.design_weights), + weights=sidecars.final_weights, + weight_entity="household", + frame=SimpleNamespace(table=lambda entity: household), + ) + paths = write_uk_target_support_sidecars(result, tmp_path / "attempt") + assert set(paths) == {"matrix", "vectors", "manifest"} + manifest = json.loads(paths["manifest"].read_text()) + assert manifest["targets"] == 3 and manifest["records"] == 6 + assert manifest["household_ids"] is True + loaded = load_uk_target_support_sidecars(tmp_path / "attempt") + assert loaded.names == sidecars.names + np.testing.assert_allclose(loaded.final_weights, sidecars.final_weights) + np.testing.assert_allclose(loaded.matrix.toarray(), sidecars.matrix.toarray()) + assert loaded.household_ids is not None + assert loaded.household_ids.tolist() == [11, 12, 13, 14, 15, 16] + # A tampered matrix is refused by its digest; a missing file by name. + sparse.save_npz( + tmp_path / "attempt" / TARGET_SUPPORT_MATRIX_FILE, + sparse.csr_array(np.eye(3, 6)), + ) + with pytest.raises(TargetSupportError, match="sha256"): + load_uk_target_support_sidecars(tmp_path / "attempt") + (tmp_path / "attempt" / TARGET_SUPPORT_MANIFEST_FILE).unlink() + with pytest.raises(TargetSupportError, match="missing"): + load_uk_target_support_sidecars(tmp_path / "attempt") + + +def test_sidecars_refuse_misaligned_vectors() -> None: + matrix = sparse.csr_array(np.ones((2, 3))) + with pytest.raises(TargetSupportError, match="weight vectors disagree"): + TargetSupportSidecars( + matrix=matrix, + names=("a", "b"), + target_vector=np.array([1.0, 2.0]), + design_weights=np.ones(3), + final_weights=np.ones(2), + household_ids=None, + ) + with pytest.raises(TargetSupportError, match="target rows disagree"): + TargetSupportSidecars( + matrix=matrix, + names=("a",), + target_vector=np.array([1.0, 2.0]), + design_weights=np.ones(3), + final_weights=np.ones(3), + household_ids=None, + ) + + +def test_verification_against_diagnostics_refuses_another_attempt() -> None: + sidecars = _sidecars() + reports = anatomy_for_targets(sidecars, ["fares", "flat"]) + diagnostics = { + "targets": [ + {"name": "fares@2025", "final_estimate": 105.0}, + {"name": "flat", "final_estimate": 13.5}, + ] + } + verify_against_diagnostics(reports, diagnostics) + with pytest.raises(TargetSupportError, match="differs from the diagnostics"): + verify_against_diagnostics( + reports, {"targets": [{"name": "fares@2025", "final_estimate": 90.0}]} + ) + with pytest.raises(TargetSupportError, match="no final_estimate"): + verify_against_diagnostics(reports, {"targets": []}) + + +def test_cli_prints_and_writes_the_reports(tmp_path: Path, capsys) -> None: + from tools.diagnose_uk_target_support import main + + sidecars = _sidecars() + result = SimpleNamespace( + problem=SimpleNamespace( + matrix=sidecars.matrix, + names=sidecars.names, + target_vector=sidecars.target_vector, + ), + initial_weights=sidecars.design_weights, + weights=sidecars.final_weights, + weight_entity="household", + frame=None, + ) + attempt = tmp_path / "attempt" + write_uk_target_support_sidecars(result, attempt) + diagnostics = attempt / "calibration_diagnostics.json" + diagnostics.write_text( + json.dumps({"targets": [{"name": "fares@2025", "final_estimate": 105.0}]}) + ) + out = tmp_path / "anatomy.json" + code = main( + [ + "--attempt-dir", + str(attempt), + "--diagnostics", + str(diagnostics), + "--prefix", + "fares", + "--stretch", + "2", + "--json", + str(out), + ] + ) + assert code == 0 + printed = capsys.readouterr().out + assert "fares@2025" in printed and ">2x" in printed + written = json.loads(out.read_text()) + assert written[0]["stretched"]["2x"]["stretched_mass"] == pytest.approx(70 / 105) diff --git a/tools/diagnose_uk_target_support.py b/tools/diagnose_uk_target_support.py new file mode 100644 index 000000000..ed15b1053 --- /dev/null +++ b/tools/diagnose_uk_target_support.py @@ -0,0 +1,141 @@ +"""Per-target weight-stretch anatomy of a UK national calibration attempt. + +Reads the target-support sidecars a national calibration attempt writes beside +its diagnostics before the terminal battery runs (``target_support_matrix.npz``, +``target_support_vectors.npz``, ``target_support_manifest.json``; see +``microcosm.build.uk_runtime.target_support``) and reports, for each requested +target: the target, design and final aggregates, the carrier count, the top +carrier concentration, the carrier weight-ratio distribution, and the share of +the target's final mass sitting on households stretched beyond declared +multiples of their design weight (3x and 5x by default), each beside the +frame-wide share of weight above the same multiple. This is the read-only +instrument behind the microcosm#890 acceptance line (the share of England +bus-fare mass on households stretched more than 3x) and the microcosm#930 +measurement; it never modifies an artifact and never runs a solve. + +When ``--diagnostics`` names the attempt's ``calibration_diagnostics.json``, +every recomputed final estimate is checked against the recorded one before a +report is printed, so a sidecar from another attempt is refused. + +Example:: + + uv run --no-sync python tools/diagnose_uk_target_support.py \\ + --attempt-dir data/ukds/acceptance/930-nts-bus/round-1 \\ + --diagnostics data/ukds/acceptance/930-nts-bus/round-1/calibration_diagnostics.json \\ + --prefix dft.bus_fare_receipts --prefix scotgov.bus --json anatomy.json +""" + +from __future__ import annotations + +import argparse +import json +import sys +from pathlib import Path + +from microcosm.build.uk_runtime.target_support import ( + DEFAULT_STRETCH_THRESHOLDS, + TargetSupportError, + anatomy_for_targets, + load_uk_target_support_sidecars, + realised_max_weight_ratio, + verify_against_diagnostics, +) + + +def _parse_args(argv: list[str] | None) -> argparse.Namespace: + parser = argparse.ArgumentParser(description=__doc__.splitlines()[0]) + parser.add_argument( + "--attempt-dir", + required=True, + type=Path, + help="directory holding the target-support sidecars", + ) + parser.add_argument( + "--diagnostics", + type=Path, + default=None, + help="the attempt's calibration_diagnostics.json (verifies the sidecars)", + ) + parser.add_argument( + "--target", + action="append", + default=[], + help="a compiled row name (name or name@period); repeatable", + ) + parser.add_argument( + "--prefix", + action="append", + default=[], + help="report every row whose name starts with this prefix; repeatable", + ) + parser.add_argument( + "--stretch", + type=float, + action="append", + default=None, + help="weight-ratio threshold for the stretched-mass buckets; repeatable", + ) + parser.add_argument("--top", type=int, default=10, help="carriers listed per row") + parser.add_argument("--json", type=Path, default=None, help="write the reports") + return parser.parse_args(argv) + + +def _percent(value: object, *, signed: bool = False) -> str: + if not isinstance(value, (int, float)): + return "n/a" + return f"{value:+.1%}" if signed else f"{value:.1%}" + + +def main(argv: list[str] | None = None) -> int: + args = _parse_args(argv) + sidecars = load_uk_target_support_sidecars(args.attempt_dir) + names: list[str] = list(args.target) + for prefix in args.prefix: + names.extend(n for n in sidecars.names if n.startswith(prefix)) + if not names: + raise SystemExit("name at least one --target or --prefix.") + seen: set[str] = set() + ordered = [n for n in names if not (n in seen or seen.add(n))] + thresholds = tuple(args.stretch) if args.stretch else DEFAULT_STRETCH_THRESHOLDS + reports = anatomy_for_targets( + sidecars, ordered, stretch_thresholds=thresholds, top=args.top + ) + if args.diagnostics is not None: + diagnostics = json.loads(args.diagnostics.read_text()) + verify_against_diagnostics(reports, diagnostics) + max_ratio = realised_max_weight_ratio(sidecars) + print( + f"attempt {args.attempt_dir}: {len(sidecars.names)} compiled rows, " + f"{len(sidecars.final_weights)} records, realised max weight ratio " + f"{max_ratio if max_ratio is None else f'{max_ratio:.3f}'}" + ) + for report in reports: + buckets = ", ".join( + f">{key}: mass {_percent(b['stretched_mass'])} " + f"(frame {_percent(b['frame_weight_share'])}), carriers " + f"{_percent(b['stretched_carriers'])}" + for key, b in report["stretched"].items() + ) + ratio = report["carrier_weight_ratio"] + print( + f"- {report['name']}: design {_percent(report['design_relative_error'], signed=True)}" + f" -> final {_percent(report['final_relative_error'], signed=True)}; " + f"carriers {report['carrier_count']}, top-1 {_percent(report['top_1_share'])}, " + f"top-5 {_percent(report['top_5_share'])}; ratio median " + f"{ratio['median'] if ratio['median'] is None else f'{ratio["median"]:.2f}'}, " + f"p90 {ratio['p90'] if ratio['p90'] is None else f'{ratio["p90"]:.2f}'}, " + f"max {ratio['max'] if ratio['max'] is None else f'{ratio["max"]:.2f}'}; " + f"{buckets}" + ) + if args.json is not None: + args.json.write_text(json.dumps(reports, indent=2) + "\n") + print(f"wrote {args.json}") + return 0 + + +if __name__ == "__main__": + try: + raise SystemExit(main()) + except TargetSupportError as exc: + print(f"error: {exc}", file=sys.stderr) + raise SystemExit(2) from exc From 37f1f17e28b97a1e8d085fce4e7fb3ab67a49572 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 16:36:03 +0100 Subject: [PATCH 03/19] Close Vahid's third-pass items on #927: declared fallback regions, conditional schema keys, per-sweep IPF residuals, the walk documented, receipts attributions (#930 C0) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The should-fixes, questions and nits of the approving review on PR #927 (three minutes before merge) were never addressed. Declarations: the lcfs stage notes and their packaged mirror no longer say the FY2024-25 Ofgem pricing sets the energy columns' level (the NEED 2024 shape at the DESNZ level and the QEP average prices paid do); the price_domestic_energy schema branch requires the connection keys whenever gas_connected is published_meter_share (the file's first if/then, refused at validation rather than in the stage); the regions the crosswalk maps to no subnational area are declared as connection_fallback_regions (Northern Ireland) and refused if they differ from the crosswalk, so the fallback is no longer inferred from a None. Receipts of convergence: iterative_proportional_fit records the cross-margin residual after every sweep (raking_sweep_residuals), the energy rake receipt carries it per fuel (sweep_residuals), and the energy_rake gate note states the tolerance governance (a rule above the observed maxima; a converged residual above it is a new ruling, never a silent re-pin) and the connection-cap rule (declared, waived only for a receipted shortfall). The gas-connection walk is documented as the greedy weight-fitting walk it is and tested on unequal weights through its skip and nearest-skipped branches; the evidence_absent_blocks plus synthetic_smoke seam is tested (an absent receipt blocks the smoke, a failed population fact check does not). Receipts Parts R and S credit the UK spec-digest move to the rebased 713b5064 (run labels untouched); Part T records that ONS 04.5.3 and 04.5.4 (about GBP 1.57bn) are vendored and unbound and that María confirmed the 04.5 sign-out on 2026-09-17. The merged PR body carries the rebased hashes. The H2 fixture, the coverage manifest and the gate-battery and certification-part digests are regenerated and re-pinned. Co-Authored-By: Claude Fable 5.1 --- changelog.d/927-round3-carry-overs.fixed.md | 1 + experiments/890-fuel-bus-energy-receipts.md | 6 +- .../src/microcosm/build/raking.py | 32 +++++++ .../spec_engine/schema/sources.schema.json | 27 ++++++ .../src/microcosm/build/uk/gates.json | 2 +- .../src/microcosm/build/uk/source_stages.json | 5 +- .../src/microcosm/build/uk/spec/sources.yaml | 4 +- .../build/uk_runtime/energy_pricing.py | 57 +++++++++--- .../tests/test_gate_battery.py | 53 +++++++++++ .../tests/test_uk_energy_pricing.py | 87 +++++++++++++++++++ .../parity/uk_spine/sources/fixture.json | 5 +- 11 files changed, 259 insertions(+), 20 deletions(-) create mode 100644 changelog.d/927-round3-carry-overs.fixed.md diff --git a/changelog.d/927-round3-carry-overs.fixed.md b/changelog.d/927-round3-carry-overs.fixed.md new file mode 100644 index 000000000..155a1e4e2 --- /dev/null +++ b/changelog.d/927-round3-carry-overs.fixed.md @@ -0,0 +1 @@ +The items Vahid's third pass on PR #927 left open are closed (microcosm#930 C0). The lcfs stage notes and their packaged mirror no longer say the FY2024-25 Ofgem pricing sets the energy columns' level (the NEED 2024 shape at the DESNZ level and the QEP average prices paid do). The `price_domestic_energy` schema branch now requires the connection keys whenever `gas_connected` is `published_meter_share` (the first `if`/`then` in `sources.schema.json`), and the regions the crosswalk maps to no subnational area are declared on the stage as `connection_fallback_regions` (Northern Ireland) and refused at runtime if they differ from the crosswalk, so the fallback is no longer inferred from a `None`. `iterative_proportional_fit` records the cross-margin residual after every sweep in `raking_sweep_residuals`, the energy rake receipt carries it per fuel as `sweep_residuals`, and the `uk_stage_lcfs_consumption_energy_rake` note states the tolerance governance (a rule above the observed maxima; a converged residual above it is a new ruling) and the connection-cap rule (declared, waived only for a receipted shortfall). The gas-connection walk is documented as the greedy weight-fitting walk it is, with a test on unequal weights that exercises the skip and nearest-skipped branches and `rows_skipped_for_weight`; the `evidence_absent_blocks` plus `synthetic_smoke` seam has a test (an absent receipt blocks the smoke, a failed population fact check does not). Receipts Parts R and S credit the UK spec-digest move to the rebased `713b5064`, Part T records that ONS 04.5.3 and 04.5.4 (about GBP 1.57bn) are vendored and unbound and that María confirmed the 04.5 sign-out, and the merged PR #927 body carries the rebased hashes. The gate-battery and certification-part digests are re-pinned. diff --git a/experiments/890-fuel-bus-energy-receipts.md b/experiments/890-fuel-bus-energy-receipts.md index b85082e5b..915bb5485 100644 --- a/experiments/890-fuel-bus-energy-receipts.md +++ b/experiments/890-fuel-bus-energy-receipts.md @@ -588,7 +588,7 @@ checks the column again with a zero clipped-row allowance. spine-s4 `b899f40a…`): the clip receipt shows 0 rows clipped low and 0 high over 16,288 households (every draw is a donor value, positive-regime fills included), the payload is identical to spine-s3, and the three transferred-phase stage gates pass (15 columns checked on the lcfs -support gate). `45aef087` also moved the UK `spec_sha256` (`d2e82feb…` → `08fbe013…`, the declaration +support gate). `713b5064` (pre-rebase `45aef087`) also moved the UK `spec_sha256` (`d2e82feb…` → `08fbe013…`, the declaration changed) and the gate digests, re-pinned in the same commit but unmentioned in its message; the H2 fixture was regenerated separately at `10d85464`. @@ -630,7 +630,7 @@ lockstep claim had gone stale. Fixes: `applied_to` (schema `required`, runtime refusal, no defaults). - The crosswalk's `area_definitions_url` is Ofgem's regional cap page (the fourteen regions with their standing charges and unit rates), with a note on the dominant-area basis. -- Attribution corrections: the UK `spec_sha256` moved at `45aef087` (Part R), the fixture was +- Attribution corrections: the UK `spec_sha256` moved at `713b5064` (pre-rebase `45aef087`; Part R), the fixture was regenerated at `12628088` and `10d85464`, not `47ea5a03` (PR body). On the spine-s4 build record the reworked gate passes with 46 cells fact-checked and the @@ -679,7 +679,7 @@ the coicop dimension; census central-heating tables (TS046, UV407; not consumed, counts carry the connection). Vendored: need_energy_facts.json (456 rows, 2023 and 2024), ons_household_expenditure_facts.json (42), desnz_domestic_energy_facts.json (155: Energy Trends plus the sixteen region/country subnational areas), qep_energy_prices.json (1,465). National -surface 614 active (613 + 04.5.1 + 04.5.2 − 04.5 signed out `superseded_by_component_targets`), +surface 614 active (613 + 04.5.1 + 04.5.2 − 04.5 signed out `superseded_by_component_targets`; ONS 04.5.3 liquid fuels, GBP 1.20bn in 2024, and 04.5.4 solid fuels, GBP 0.35bn, are vendored in `ons_household_expenditure_facts.json` and unbound because the frame models neither fuel, so the sign-out leaves about GBP 1.57bn of household fuel spend outside the bound rows; the sign-out's `approved_by juaristi22`, 2026-09-16, was confirmed by María on 2026-09-17 at the #930 plan review), local surface unchanged (20,885), compile-parity receipts rebuilt. The published facts (FY2024-25 unless stated): diff --git a/packages/microcosm-build/src/microcosm/build/raking.py b/packages/microcosm-build/src/microcosm/build/raking.py index dcabe29c5..8d26a9099 100644 --- a/packages/microcosm-build/src/microcosm/build/raking.py +++ b/packages/microcosm-build/src/microcosm/build/raking.py @@ -39,6 +39,13 @@ def iterative_proportional_fit( Populated zero-current-mean cells with positive targets are recorded in the returned frame's ``raking_zero_current_cells`` evidence attribute. Callers that require fail-closed behavior can set ``fail_on_unattainable``. + + The fit runs a fixed number of sweeps with no convergence test; so that a + caller can show whether the terminal cross-margin residual is converged + or merely truncated, the maximum absolute relative deviation of any + populated cell mean from its positive target is recorded after every + sweep in the returned frame's ``raking_sweep_residuals`` attribute (one + value per sweep, the last being the residual of the returned frame). """ if iterations < 1: @@ -61,6 +68,29 @@ def iterative_proportional_fit( raise ValueError("raking weights must be nonnegative") zero_current_cells: list[dict[str, object]] = [] + sweep_residuals: list[float] = [] + + def _max_abs_relative_residual() -> float: + worst = 0.0 + for margin in margins: + for category, target_by_column in margin.targets.items(): + mask = result[margin.column] == category + if not bool(mask.any()): + continue + for column in columns: + if column not in target_by_column: + continue + target = float(target_by_column[column]) + if not np.isfinite(target) or target <= 0: + continue + current = _cell_mean( + result.loc[mask, column], + None if weights is None else weights.loc[mask], + ) + if current > 0 and np.isfinite(current): + worst = max(worst, abs(current / target - 1.0)) + return worst + for _ in range(iterations): for margin in margins: if margin.column not in result: @@ -99,7 +129,9 @@ def iterative_proportional_fit( ) continue result.loc[mask, column] *= target / current + sweep_residuals.append(_max_abs_relative_residual()) result.attrs["raking_zero_current_cells"] = tuple(zero_current_cells) + result.attrs["raking_sweep_residuals"] = tuple(sweep_residuals) return result 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 f988aed9f..e7603ab43 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 @@ -8805,6 +8805,13 @@ "positive_gas_spend" ] }, + "connection_fallback_regions": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, "disconnect_rule": { "enum": [ "lowest_drawn_gas_first" @@ -8827,6 +8834,26 @@ "actual_temperature" ] } + }, + "if": { + "required": [ + "gas_connected" + ], + "properties": { + "gas_connected": { + "const": "published_meter_share" + } + } + }, + "then": { + "required": [ + "connection_resource", + "connection_period_value", + "connection_rule", + "connection_fallback", + "connection_fallback_regions", + "disconnect_rule" + ] } } ], diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 4c6e1321b..cfb761a3c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -244,7 +244,7 @@ "maximum_relative_deviation": 0.025, "maximum_connected_share_deviation": 0.005 }, - "notes": "Stage-time energy check (microcosm#890 F, chronicle#270). María's ruling (2026-09-15, PR #927): 'I'm not sure why we are comparing against NEED as a gate in the first place if that is not what we are calibrating, but I agree we should implement Vahid's recommended fix and move the fix to before calibration.' Fact checks on the lcfs energy_rake receipt, every published value recomputed at gate time from the vendored rows the stage declares: each cell's shape target is the vendored NEED 2024 mean (need_energy_facts.json, margins_period_value), each fuel's level is the vendored DESNZ Energy Trends domestic consumption at actual temperature over the four FY2024-25 quarters (desnz_domestic_energy_facts.json) with the level factor equal to that total over the frame's pre-level total and the levelled frame total equal to the published one, each cell's target is shape times factor, and every region with a published gas-connected share (DESNZ subnational gas meters over electricity meters, 2024) sits within 0.5 points of it after the imposition unless the draw could not fill it (a receipted shortfall). The residual check holds the maximum absolute relative deviation of any cell mean from its levelled target, per margin (income band, tenure, property type, region) and fuel, electricity over every household of a cell and gas over its gas-connected households, to one fixed 2.5 % tolerance on the IPF's cross-margin residual (region is swept last and fits to machine precision by construction, so the tolerance binds the earlier three; a declared rule set above the observed maxima, not a fact: spine-s3 on NEED 2023 showed income 1.65 %, tenure 1.29 %, accommodation 0.83 %; spine-s5 on the NEED 2024 shape with the published connection showed income 2.16 % electricity / 1.97 % gas, accommodation 1.46 %, tenure 1.31 %, which is why the 2 % rule of spine-s3 moved to 2.5 %). This gate replaced the two NEED mean-spend anchors that uk_aggregate_admin measured on the calibrated frame; the calibrated frame is held to the bound ONS 04.5.1 electricity and 04.5.2 gas rows, and the gap between the DESNZ-volume-times-QEP-price level the stage sets and the ONS national-accounts spend is the published-source residual PR #927 receipts Part T records, not a gate. The entry is a population_fact_check: a synthetic smoke build (the staging smoke over the H2 fixture) records its outcome without blocking, because the fixture is not the population NEED, DESNZ and the meter counts describe; every licensed build blocks on it." + "notes": "Stage-time energy check (microcosm#890 F, chronicle#270). María's ruling (2026-09-15, PR #927): 'I'm not sure why we are comparing against NEED as a gate in the first place if that is not what we are calibrating, but I agree we should implement Vahid's recommended fix and move the fix to before calibration.' Fact checks on the lcfs energy_rake receipt, every published value recomputed at gate time from the vendored rows the stage declares: each cell's shape target is the vendored NEED 2024 mean (need_energy_facts.json, margins_period_value), each fuel's level is the vendored DESNZ Energy Trends domestic consumption at actual temperature over the four FY2024-25 quarters (desnz_domestic_energy_facts.json) with the level factor equal to that total over the frame's pre-level total and the levelled frame total equal to the published one, each cell's target is shape times factor, and every region with a published gas-connected share (DESNZ subnational gas meters over electricity meters, 2024) sits within 0.5 points of it after the imposition unless the draw could not fill it (a receipted shortfall). The residual check holds the maximum absolute relative deviation of any cell mean from its levelled target, per margin (income band, tenure, property type, region) and fuel, electricity over every household of a cell and gas over its gas-connected households, to one fixed 2.5 % tolerance on the IPF's cross-margin residual (region is swept last and fits to machine precision by construction, so the tolerance binds the earlier three; a declared rule set above the observed maxima, not a fact: spine-s3 on NEED 2023 showed income 1.65 %, tenure 1.29 %, accommodation 0.83 %; spine-s5 on the NEED 2024 shape with the published connection showed income 2.16 % electricity / 1.97 % gas, accommodation 1.46 %, tenure 1.31 %, which is why the 2 % rule of spine-s3 moved to 2.5 %). This gate replaced the two NEED mean-spend anchors that uk_aggregate_admin measured on the calibrated frame; the calibrated frame is held to the bound ONS 04.5.1 electricity and 04.5.2 gas rows, and the gap between the DESNZ-volume-times-QEP-price level the stage sets and the ONS national-accounts spend is the published-source residual PR #927 receipts Part T records, not a gate. The entry is a population_fact_check: a synthetic smoke build (the staging smoke over the H2 fixture) records its outcome without blocking, because the fixture is not the population NEED, DESNZ and the meter counts describe; every licensed build blocks on it. Tolerance governance (Vahid's third pass on PR #927): maximum_relative_deviation is a rule set above the observed maxima, not a fact; the rake runs a fixed number of sweeps and the receipt now records the cross-margin residual after every sweep (sweep_residuals), so the terminal residual is shown converged, not truncated, and a vintage whose converged residual exceeds the rule is a new ruling for María, never a silent re-pin. maximum_connected_share_deviation is declared, not derived from the walk: the greedy weight-fitting walk lands within a fraction of one household weight of the published share, and the check is waived only for a region whose draw cannot fill its published share (the shortfall is receipted and reported here), never for a region above it. The regions the crosswalk maps to no subnational area are declared on the stage (connection_fallback_regions, Northern Ireland) and refused if they differ from the crosswalk." }, { "id": "uk_stage_etb_vat_support", 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 eb2fad94f..d89af16eb 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1841,6 +1841,9 @@ "connection_period_value": 2024, "connection_rule": "gas_meters_over_electricity_meters", "connection_fallback": "positive_gas_spend", + "connection_fallback_regions": [ + "NORTHERN_IRELAND" + ], "disconnect_rule": "lowest_drawn_gas_first", "margins_resource": "need_energy_facts.json", "margins_period_value": 2024, @@ -1997,7 +2000,7 @@ "gas_consumption", "has_fuel_consumption" ], - "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED rake and the FY2024-25 Ofgem pricing set their level." + "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level." }, { "stage": "etb_vat", 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 3d6b0c9ae..0aab2000c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1388,6 +1388,8 @@ stages: connection_period_value: 2024 connection_rule: gas_meters_over_electricity_meters connection_fallback: positive_gas_spend + connection_fallback_regions: + - NORTHERN_IRELAND disconnect_rule: lowest_drawn_gas_first margins_resource: need_energy_facts.json margins_period_value: 2024 @@ -1510,7 +1512,7 @@ stages: - electricity_consumption - gas_consumption - has_fuel_consumption - notes: Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED rake and the FY2024-25 Ofgem pricing set their level. + notes: Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level. - stage: etb_vat survey: Effects of Taxes and Benefits 1977-2024 source: UK Data Service SN 8856 Effects of Taxes and Benefits household tab and cited VAT anchor resource. diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/energy_pricing.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/energy_pricing.py index 0271b62f7..8c85d7403 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/energy_pricing.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/energy_pricing.py @@ -430,8 +430,26 @@ def published_gas_connected_shares( f"connection_fallback must be {GAS_CONNECTED_POSITIVE_SPEND!r} (the rule " "for regions without a published meter count)." ) + declared_fallback = parameters.get("connection_fallback_regions") + if ( + not isinstance(declared_fallback, list) + or not declared_fallback + or not all(isinstance(region, str) and region for region in declared_fallback) + ): + raise ValueError( + "connection_fallback_regions must name every FRS region that has no " + "published meter count (a non-empty list of region names)." + ) + fallback_regions = {str(region) for region in declared_fallback} crosswalk = load_ofgem_region_crosswalk() areas = crosswalk["subnational_area_mapping"] + undeclared = sorted(str(region) for region, area in areas.items() if area is None) + if set(undeclared) != fallback_regions: + raise ValueError( + "connection_fallback_regions must be exactly the regions the crosswalk " + f"maps to no subnational area: declared {sorted(fallback_regions)}, " + f"crosswalk {undeclared}." + ) shares: dict[str, float | None] = {} by_region: dict[str, dict[str, Any]] = {} for frs_region, area in areas.items(): @@ -477,6 +495,7 @@ def published_gas_connected_shares( "resource": resource, "period_value": period_value, "fallback": fallback, + "fallback_regions": sorted(fallback_regions), "by_region": by_region, } return shares, receipt @@ -492,18 +511,20 @@ def impose_gas_connection( ) -> tuple[np.ndarray, dict[str, Any]]: """The gas-connected mask after imposing each region's published share. - Within a region whose design-weighted share of gas-positive households - exceeds the published share, gas-positive households are disconnected in - ascending order of drawn gas kWh (a trace of diary gas is the likeliest - false connection) until the excess weight is removed: a household whose - weight would overshoot the remaining excess is skipped (it stays - connected) and the walk continues to lighter households, then the skipped - household nearest the remainder is taken if that brings the share nearer - the published one, so the achieved share sits within a fraction of one - household weight of the published share. A region below its published - share keeps every gas-positive household (the draw cannot create - connections) and the shortfall is receipted. Regions with no published - share (``None``) keep the positive-gas rule. + A greedy weight-fitting walk, not a fitted threshold. Within a region + whose design-weighted share of gas-positive households exceeds the + published share, gas-positive households are walked in ascending order of + drawn gas kWh (a trace of diary gas is the likeliest false connection): + a household is disconnected when its weight fits inside the remaining + excess, skipped (it stays connected) when it would overshoot, and after + the walk the skipped household nearest the remainder is disconnected if + that brings the share nearer the published one. The achieved share + therefore sits within a fraction of one household weight of the published + share; ``rows_skipped_for_weight`` counts the households the walk passed + over. A region below its published share keeps every gas-positive + household (the draw cannot create connections) and the shortfall is + receipted. Regions with no published share (``None``, the stage's + declared ``connection_fallback_regions``) keep the positive-gas rule. """ if disconnect_rule != DISCONNECT_LOWEST_DRAWN_GAS_FIRST: @@ -563,6 +584,7 @@ def impose_gas_connection( drop.append(nearest) remaining -= weight[nearest] drop_index = np.asarray(drop, dtype=int) + dropped = set(drop) connected[drop_index] = False after = float(weight[rows[connected[rows]]].sum()) / total entry.update( @@ -571,7 +593,7 @@ def impose_gas_connection( "share_after": after, "rows_disconnected": int(len(drop_index)), "rows_skipped_for_weight": int( - sum(1 for i in skipped if i not in set(drop)) + sum(1 for i in skipped if i not in dropped) ), "weight_disconnected": float(weight[drop_index].sum()), "shortfall": 0.0, @@ -928,6 +950,11 @@ def rake_energy_kwh( weight_column=weight_column, ) zero_cells = list(raked.attrs.get("raking_zero_current_cells", ())) + sweep_residuals = { + ELECTRICITY_KWH: [ + float(v) for v in raked.attrs.get("raking_sweep_residuals", ()) + ] + } gas_raked = iterative_proportional_fit( frame.loc[connected], columns=(GAS_KWH,), @@ -936,6 +963,9 @@ def rake_energy_kwh( weight_column=weight_column, ) zero_cells.extend(gas_raked.attrs.get("raking_zero_current_cells", ())) + sweep_residuals[GAS_KWH] = [ + float(v) for v in gas_raked.attrs.get("raking_sweep_residuals", ()) + ] raked.loc[connected, GAS_KWH] = gas_raked[GAS_KWH].to_numpy(dtype=float) raked.loc[~connected, GAS_KWH] = 0.0 weight_values = ( @@ -982,6 +1012,7 @@ def rake_energy_kwh( "gas_connected_rows": int(connected.sum()), "rows": int(len(frame)), "zero_current_cells": zero_cells, + "sweep_residuals": sweep_residuals, "level_factor": dict(level_factor), "level": level_receipt, "fit": fit, diff --git a/packages/microcosm-build/tests/test_gate_battery.py b/packages/microcosm-build/tests/test_gate_battery.py index 5c3f4de99..468d5e95c 100644 --- a/packages/microcosm-build/tests/test_gate_battery.py +++ b/packages/microcosm-build/tests/test_gate_battery.py @@ -864,3 +864,56 @@ def run(*, synthetic_smoke: bool, release_candidate: bool = False): plain.run_phase("terminal", EvidenceContext()) with pytest.raises(GateBatteryBlockedError): plain.enforce("terminal", mode=BlockingMode.BLOCKS_ARTIFACT) + + +def test_evidence_absent_blocks_a_synthetic_smoke_even_on_a_population_fact_check( + tmp_path, signing_env +) -> None: + """The two flags sit on different status branches, by design. + + ``synthetic_smoke`` excuses a *failed* population fact check (the fixture + is not the population); ``evidence_absent_blocks`` forces an *absent* + receipt to block in every posture, the synthetic smoke included. A stage + that runs on the fixture but leaves no receipt is a wiring fault, not a + population mismatch, so the smoke blocks on it. + """ + + manifest = _manifest( + [ + _entry( + "fact", + gate="weights_audit", + population_fact_check=True, + evidence_absent_blocks=True, + ) + ], + ["terminal"], + ) + battery = GateBatteryRun( + manifest, + release_id="xx-test-build", + report_path=tmp_path / "smoke-absent.json", + release_candidate=False, + synthetic_smoke=True, + ) + battery.run_phase("terminal", EvidenceContext()) + with pytest.raises(GateBatteryBlockedError): + battery.enforce("terminal", mode=BlockingMode.BLOCKS_ARTIFACT) + payload = battery.report_payload() + assert payload["synthetic_smoke"] is True + assert payload["gates"]["fact"]["status"] == "evidence_absent" + # The same entry without the evidence flag is excused on absence too: + # nothing then blocks the smoke, and the report still says absent. + lenient = GateBatteryRun( + _manifest( + [_entry("fact", gate="weights_audit", population_fact_check=True)], + ["terminal"], + ), + release_id="xx-test-build", + report_path=tmp_path / "smoke-absent-lenient.json", + release_candidate=False, + synthetic_smoke=True, + ) + lenient.run_phase("terminal", EvidenceContext()) + assert lenient.enforce("terminal", mode=BlockingMode.BLOCKS_ARTIFACT) is False + assert lenient.report_payload()["gates"]["fact"]["status"] == "evidence_absent" diff --git a/packages/microcosm-build/tests/test_uk_energy_pricing.py b/packages/microcosm-build/tests/test_uk_energy_pricing.py index ec439797c..9183366e9 100644 --- a/packages/microcosm-build/tests/test_uk_energy_pricing.py +++ b/packages/microcosm-build/tests/test_uk_energy_pricing.py @@ -235,6 +235,9 @@ def test_published_gas_connected_shares_are_meters_over_meters() -> None: } assert shares["NORTHERN_IRELAND"] is None assert receipt["by_region"]["NORTHERN_IRELAND"]["rule"] == "positive_gas_spend" + # The fallback is declared, not inferred: the stage names the regions the + # crosswalk maps to no subnational area, and the receipt echoes them. + assert receipt["fallback_regions"] == ["NORTHERN_IRELAND"] def meters(area: str, fuel: str) -> float: rows = vendored_rows( @@ -266,6 +269,26 @@ def meters(area: str, fuel: str) -> float: (lambda p: p.update(connection_rule="census"), "connection_rule"), (lambda p: p.update(connection_fallback="none"), "connection_fallback"), (lambda p: p.update(connection_period_value=2019), "expected one vendored row"), + # A declared fallback list that names a region the crosswalk maps to an + # area, omits one it maps to none, or is absent altogether is refused. + ( + lambda p: p.update(connection_fallback_regions=["WALES"]), + "connection_fallback_regions must be exactly", + ), + ( + lambda p: p.update( + connection_fallback_regions=["NORTHERN_IRELAND", "WALES"] + ), + "connection_fallback_regions must be exactly", + ), + ( + lambda p: p.pop("connection_fallback_regions"), + "connection_fallback_regions must name", + ), + ( + lambda p: p.update(connection_fallback_regions=[]), + "connection_fallback_regions must name", + ), ): parameters = dict(_declared()) mutation(parameters) @@ -305,6 +328,48 @@ def test_impose_gas_connection_disconnects_the_smallest_draws_first() -> None: ) +def test_impose_gas_connection_skips_a_household_whose_weight_would_overshoot() -> None: + """The greedy walk with unequal weights: skip, then take the nearest skipped. + + One region, every household gas-positive, weights 1, 1, 2.5, 1, 1 (total + 6.5) and a published share of 0.2, so 5.2 of weight must go. Walking up + the drawn gas: the two lightest households go (remaining 3.2), the 2.5 + household fits and goes (0.7), the last two would overshoot and are + skipped; after the walk the skipped household nearest the remainder + (weight 1, |1 - 0.7| = 0.3 < 0.7) is taken because it brings the share + nearer the published one, and the other stays connected and is counted + as skipped for weight. + """ + + gas = np.array([1.0, 2.0, 3.0, 4.0, 5.0]) + weights = np.array([1.0, 1.0, 2.5, 1.0, 1.0]) + region = np.array(["LONDON"] * 5) + connected, receipt = impose_gas_connection( + gas, frs_region=region, weights=weights, shares={"LONDON": 0.2} + ) + assert connected.tolist() == [False, False, False, False, True] + london = receipt["by_region"]["LONDON"] + assert london["share_before"] == pytest.approx(1.0) + assert london["share_after"] == pytest.approx(1.0 / 6.5) + assert london["rows_disconnected"] == 4 + assert london["rows_skipped_for_weight"] == 1 + assert london["weight_disconnected"] == pytest.approx(5.5) + assert london["shortfall"] == 0.0 + # The same walk where taking the nearest skipped household would move the + # share further from the published one leaves it connected: weights + # 1, 1, 10, 1, 1 (total 14) and a share of 0.5 remove 7; the 10 household + # is skipped and, at |10 - 3| = 7, not nearer than the remainder of 3. + weights = np.array([1.0, 1.0, 10.0, 1.0, 1.0]) + connected, receipt = impose_gas_connection( + gas, frs_region=region, weights=weights, shares={"LONDON": 0.5} + ) + assert connected.tolist() == [False, False, True, False, False] + london = receipt["by_region"]["LONDON"] + assert london["share_after"] == pytest.approx(10.0 / 14.0) + assert london["rows_disconnected"] == 4 + assert london["rows_skipped_for_weight"] == 1 + + def test_published_level_is_the_fiscal_year_sum_of_energy_trends_quarters() -> None: level, receipt = published_energy_level(_declared()) quarters = fiscal_year_quarters("2024-04-01") @@ -489,6 +554,28 @@ def _synthetic_rake_receipt(n: int = 1200): return margins, level, raked, weights, receipt +def test_rake_receipt_records_one_cross_margin_residual_per_sweep() -> None: + """The IPF's terminal residual is shown to be converged, not truncated. + + ``iterative_proportional_fit`` runs a fixed 50 sweeps; the receipt carries + the maximum absolute relative cell deviation after every sweep for each + fuel, and the last value is the residual the ``energy_rake`` gate holds + to its declared tolerance. + """ + + _, _, _, _, receipt = _synthetic_rake_receipt() + residuals = receipt["sweep_residuals"] + assert set(residuals) == {ELECTRICITY_KWH, GAS_KWH} + for fuel in (ELECTRICITY_KWH, GAS_KWH): + series = residuals[fuel] + assert len(series) == receipt["iterations"] == 50 + assert all(np.isfinite(v) and v >= 0 for v in series) + # Converged: the last two sweeps agree to well inside the gate's + # tolerance, and the walk does not end higher than it started. + assert abs(series[-1] - series[-2]) < 1e-3 + assert series[-1] <= series[0] + 1e-12 + + def test_rake_fit_targets_lockstep_with_the_vendored_need_rows() -> None: """Every shape target is the vendored NEED 2024 mean; the target is shape x level.""" 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 f5a0abf09..94a95b485 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 @@ -3000,7 +3000,7 @@ "gas_consumption", "has_fuel_consumption" ], - "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (Mar\u00eda's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED rake and the FY2024-25 Ofgem pricing set their level.", + "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (Mar\u00eda's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level.", "operations": [ { "annualization_weeks": 52.17857142857143, @@ -3303,6 +3303,9 @@ "gas": "gas_consumption" }, "connection_fallback": "positive_gas_spend", + "connection_fallback_regions": [ + "NORTHERN_IRELAND" + ], "connection_period_value": 2024, "connection_resource": "desnz_domestic_energy_facts.json", "connection_rule": "gas_meters_over_electricity_meters", From bd36575cf476c4598b5c0677e1ebb5a522db3297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:05:49 +0100 Subject: [PATCH 04/19] =?UTF-8?q?Impute=20local-bus=20journeys=20from=20th?= =?UTF-8?q?e=20NTS=20microdata,=20price=20bus=20fares=20at=20the=20publish?= =?UTF-8?q?ed=20yield,=20fence=20the=20support=20rake=20(#930=20C4?= =?UTF-8?q?=E2=80=93C7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit C4+C5, the stage: a person-grain `nts_bus_travel` stage between `was_wealth` and `lcfs_consumption` reads the NTS Household, Individual and Trip tabs (UKDS SN 5340, EUL; artifact pins are placeholders refused at runtime until the licensed tabs land) through a declared codebook, fits one regime-gated QRF on the frequency-of-use band, assigns the diary's band means per series (bus in London, other local bus) and residence group, and emits the statutory concessionary eligibility per area. Gates: a support clip and a `bus_travel_facts` population fact check against the vendored NTS0313 and NTS0303 rows; NTS0205 car availability is a receipt line. Graph, kernel registry, spine tool, coverage manifest, export surface, contract scope and the H2 fixture (synthetic NTS tabs, 30 stages) carry the stage. C6, the pricing: `assign_bus_use_incidence` and the fare cells of `rake_to_vendored_facts` leave the lcfs declaration; `price_bus_journeys` sets `bus_fare_spending` as the household's non-eligible persons' trips times boardings per resident trip (BUS01 over NTS0705a times ONS population) times the yield per fare-paying boarding (BUS05ai receipts over journeys less concessionary journeys) per area, Scotland and Northern Ireland from their own receipts with England's rate as the declared proxy, Wales unpriced (raw draw, clipped). The chain still conditions on the raw draw. A `bus_pricing` gate recomputes every factor from the vendored rows. C7, the support side: the ETB `bus_subsidy_spending` rake stays and gains a `fact_rake` gate (every cell recomputed through the stage's own declaration, totals after the rake checked, the NI cell jointly over bus and rail, a skipped cell fails closed); `record_support_per_journey` records the value-side alternative beside the raked total, never applied. Digests re-pinned; `ci_test_groups --verify` ok. One commit for the four chunks: their derived surfaces (fixture, coverage manifest, digests, pins) interleave, so intermediate commits would not each have been green. Co-Authored-By: Claude Fable 5.1 --- ...0-bus-fares-priced-per-boarding.changed.md | 1 + ...us-support-per-journey-diagnostic.added.md | 1 + changelog.d/930-nts-bus-travel-stage.added.md | 1 + .../src/microcosm/build/source_manifest.py | 6 + .../spec_engine/schema/sources.schema.json | 1026 ++++++++++++ .../microcosm/build/uk/dft_bus_journeys.json | 7 +- .../src/microcosm/build/uk/gates.json | 89 +- .../uk/ledger_fact_vendor_selections.json | 19 +- .../build/uk/nts_bus_use_frequency.json | 4 +- .../build/uk/nts_car_availability.json | 4 +- .../microcosm/build/uk/nts_trip_rates.json | 4 +- .../src/microcosm/build/uk/source_stages.json | 746 +++++++-- .../src/microcosm/build/uk/spec/sources.yaml | 572 ++++++- .../build/uk_runtime/battery_bindings.py | 8 + .../build/uk_runtime/bus_fare_pricing.py | 466 ++++++ .../uk_runtime/bus_support_per_journey.py | 195 +++ .../build/uk_runtime/bus_use_incidence.py | 8 +- .../build/uk_runtime/calibration_run.py | 4 + .../build/uk_runtime/etb_services.py | 51 + .../src/microcosm/build/uk_runtime/graph.py | 16 + .../build/uk_runtime/graph_kernels.py | 23 +- .../build/uk_runtime/lcfs_consumption.py | 265 +-- .../build/uk_runtime/nts_bus_travel.py | 1438 +++++++++++++++++ .../build/uk_runtime/stage_health.py | 343 ++++ .../build/uk_runtime/terminal_gates.py | 7 + .../tests/test_country_spec.py | 9 + .../tests/test_uk_bus_fare_pricing.py | 252 +++ .../tests/test_uk_bus_support_per_journey.py | 193 +++ .../tests/test_uk_bus_use_incidence.py | 70 +- .../tests/test_uk_fact_raking.py | 66 +- .../tests/test_uk_frs_spine.py | 18 +- .../microcosm-build/tests/test_uk_graph.py | 7 + .../tests/test_uk_lcfs_consumption.py | 102 +- .../tests/test_uk_nts_bus_travel.py | 481 ++++++ .../tests/test_uk_release_input_coverage.py | 1 + .../tests/test_uk_source_stages.py | 15 +- .../tests/test_uk_stage_health.py | 223 +++ .../src/microcosm/data/contract.py | 17 + .../microcosm-data/tests/test_contract.py | 8 + .../parity/uk_spine/sources/fixture.json | 766 +++++++-- .../parity/uk_spine/sources/nts_household.csv | 65 + .../uk_spine/sources/nts_individual.csv | 161 ++ .../parity/uk_spine/sources/nts_trip.csv | 641 ++++++++ .../tests/test_acceptance_h_parity.py | 4 +- tools/build_uk_frs_spine.py | 51 + ...uild_uk_release_input_coverage_manifest.py | 4 + tools/graph_uk_spine_fixture.py | 111 +- 47 files changed, 7904 insertions(+), 665 deletions(-) create mode 100644 changelog.d/930-bus-fares-priced-per-boarding.changed.md create mode 100644 changelog.d/930-bus-support-per-journey-diagnostic.added.md create mode 100644 changelog.d/930-nts-bus-travel-stage.added.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/bus_fare_pricing.py create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py create mode 100644 packages/microcosm-build/tests/test_uk_bus_fare_pricing.py create mode 100644 packages/microcosm-build/tests/test_uk_bus_support_per_journey.py create mode 100644 packages/microcosm-build/tests/test_uk_nts_bus_travel.py create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_household.csv create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv diff --git a/changelog.d/930-bus-fares-priced-per-boarding.changed.md b/changelog.d/930-bus-fares-priced-per-boarding.changed.md new file mode 100644 index 000000000..1ebe90b02 --- /dev/null +++ b/changelog.d/930-bus-fares-priced-per-boarding.changed.md @@ -0,0 +1 @@ +`bus_fare_spending` is no longer level-set by the lcfs stage. The #890 take-up incidence draw (`assign_bus_use_incidence`) and the fare rake to the DfT, Scottish and Translink receipts (`rake_to_vendored_facts` on `bus_fare_spending`) leave the lcfs declaration; a declared `price_bus_journeys` step (`uk_runtime/bus_fare_pricing.py`, microcosm#930) sets the column as the sum over the household's non-eligible persons of the `nts_bus_travel` stage's journeys times boardings per resident trip (the vendored BUS01 journeys over the vendored NTS0705a trips per resident times the ONS population) times the yield per fare-paying boarding (BUS05ai receipts over journeys less concessionary journeys), per area: bus-in-London trips take the London area's price for every resident, other-local-bus trips the price of the residence area (England outside London; Scotland and Northern Ireland from their own receipts and journeys with England's trip rate as the declared proxy). Wales is unpriced and keeps the chain's raw draw clipped to donor support (María's ruling, 2026-09-17). The chain still draws `bus_fare_spending` so later targets condition on the same raw draw; the emitted column is the priced value. The receipt carries every published input with its source records, the derived factors, the frame-implied boardings beside the published ones and the frame's eligible trip share beside the publisher's concessionary boarding share, with the algebra stated: the design-weight fit of the bound receipts targets is a survey-versus-survey composition check times a survey-versus-admin concession check, never a level the stage set. A stage-time `bus_pricing` gate recomputes every factor from the vendored rows (`uk_stage_lcfs_consumption_bus_pricing`, a population fact check); `dft_bus_journeys.json` gains its consumers and `nts_bus_use_frequency.json` loses the lcfs stage. diff --git a/changelog.d/930-bus-support-per-journey-diagnostic.added.md b/changelog.d/930-bus-support-per-journey-diagnostic.added.md new file mode 100644 index 000000000..e12108a42 --- /dev/null +++ b/changelog.d/930-bus-support-per-journey-diagnostic.added.md @@ -0,0 +1 @@ +The ETB `bus_subsidy_spending` rake to the published net support (kept, per the #930 plan's default) is now fenced at stage time and measured against a value-side alternative (microcosm#930 C7, the #890 support-side leftover). A `fact_rake` stage-health check (`uk_stage_etb_services_support_rake`, a population fact check) recomputes every declared cell's published value from the vendored rows through the stage's own declaration, requires the receipt's cells to equal it and each cell's design-weighted total after the rake to equal its published value (the Northern Ireland cell jointly over bus and rail), and fails closed on a skipped cell; the #890 rake had no fence. A declared `record_support_per_journey` step (`uk_runtime/bus_support_per_journey.py`) records, per residence area where DfT publishes the components (London, England outside London), what pricing support from the frame's journeys would give: the BUS05 concessionary travel reimbursement per concessionary boarding times the frame's eligible boardings plus the rest of the net support per boarding times every boarding, with boardings the `nts_bus_travel` trips times the fare pricing's boardings per resident trip, beside the raked column's design-weighted total. It is a receipt (`support_per_journey`, `applied: false`), never a value: retiring the support rake is María's ruling with those numbers in hand. `dft_bus_journeys.json` names its two new consumers. diff --git a/changelog.d/930-nts-bus-travel-stage.added.md b/changelog.d/930-nts-bus-travel-stage.added.md new file mode 100644 index 000000000..196cd4240 --- /dev/null +++ b/changelog.d/930-nts-bus-travel-stage.added.md @@ -0,0 +1 @@ +A person-grain `nts_bus_travel` stage joins the UK spine between `was_wealth` and `lcfs_consumption` (microcosm#930, the structural fix María ruled on 2026-09-15 for microcosm#890's rake-then-bind bus fares). It reads the National Travel Survey microdata (UKDS SN 5340, End User Licence; Household, Individual and Trip tables pinned like the other licensed donors; England residents only since 2013) through a declared codebook (`clean_nts_travel_tables`: column names, region, income-band, sex, main-mode and frequency codes, survey years, banded ages), fits one regime-gated QRF on the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band) conditioned on age band, sex, cars, household size, the three-band gross household income and region (`impute_bus_use_band`, identity-keyed uniforms, rounded to the nearest band, devolved recipients on a declared proxy region), assigns each person the diary's weighted mean annual local-bus trips for their band and residence group split into the bus-in-London and other-local-bus series (`assign_trips_from_band_means`, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a household sum `household_local_bus_trips`), and emits the statutory concessionary eligibility of the person's area (`assign_bus_pass_eligibility`: England outside London at 66, London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 65+). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate, receipted as such. Stage-time gates: a support clip on the band and trips, and `bus_travel_facts`, a population fact check that recomputes the NTS0313 user share and the NTS0303 trips per person from the vendored rows; the frame's car availability against NTS0205 is a receipt line. The artifact pins are placeholders refused at runtime until the licensed tabs land; the H2 fixture drives the stage with synthetic tabs (30 stages), and the graph, kernel registry, spine tool (`--nts-household-tab`, `--nts-individual-tab`, `--nts-trip-tab`), coverage manifest, export surface and gate digests carry the stage. diff --git a/packages/microcosm-build/src/microcosm/build/source_manifest.py b/packages/microcosm-build/src/microcosm/build/source_manifest.py index 4d9fb1ab5..dec5dbcb2 100644 --- a/packages/microcosm-build/src/microcosm/build/source_manifest.py +++ b/packages/microcosm-build/src/microcosm/build/source_manifest.py @@ -47,11 +47,13 @@ "assign_binary_from_rate", "assign_binary_with_anchored_residual", "assign_bus_use_incidence", + "assign_bus_pass_eligibility", "assign_clipped_normal", "assign_period_constant", "assign_student_loan_plan_cohorts", "assign_main_asset_type", "assign_residential_property_flag", + "assign_trips_from_band_means", "assign_uniform_draw", "aggregate_person_to_benunit", "allocate_per_capita_from_cell_table", @@ -66,6 +68,7 @@ "classify_cgt_band_facts_with_reviewed_fence", "classify_hmrc_income_facts_with_reviewed_fences", "clone_records", + "clean_nts_travel_tables", "convert_donors_to_target_stock", "convert_interest_to_structural_mortgage_inputs", "compute_ratio", @@ -114,6 +117,7 @@ "gate_distributional_effective_mass", "gate_zero_weight_strata", "head_carry", + "impute_bus_use_band", "join", "impute_retirement_contributions_to_puf_support", "impute_childcare_to_puf_support", @@ -130,6 +134,8 @@ "iterative_proportional_fit", "pair_clone_households_to_originals", "price_domestic_energy", + "price_bus_journeys", + "record_support_per_journey", "rake_to_vendored_facts", "map_columns", "map_coded_amounts", 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 e7603ab43..f9fa4d23d 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 @@ -8855,6 +8855,1032 @@ "disconnect_rule" ] } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "lowercase_columns", + "survey_years", + "cars_clip", + "age_band_edges", + "columns", + "codes", + "codebook_status" + ], + "properties": { + "kind": { + "const": "clean_nts_travel_tables" + }, + "lowercase_columns": { + "type": "boolean" + }, + "survey_years": { + "type": "array", + "items": { + "type": "integer" + } + }, + "cars_clip": { + "type": "array", + "items": { + "type": "integer" + } + }, + "age_band_edges": { + "type": "array", + "items": { + "type": "integer" + } + }, + "columns": { + "type": "object", + "additionalProperties": false, + "required": [ + "household_id", + "individual_id", + "trip_id", + "survey_year", + "region", + "income_band", + "cars", + "household_size", + "household_weight", + "age_band", + "sex", + "main_mode", + "trip_weight", + "short_walk_multiplier" + ], + "properties": { + "household_id": { + "type": "string" + }, + "individual_id": { + "type": "string" + }, + "trip_id": { + "type": "string" + }, + "survey_year": { + "type": "string" + }, + "region": { + "type": "string" + }, + "income_band": { + "type": "string" + }, + "cars": { + "type": "string" + }, + "household_size": { + "type": "string" + }, + "household_weight": { + "type": "string" + }, + "age_band": { + "type": "string" + }, + "sex": { + "type": "string" + }, + "frequency": { + "type": "string" + }, + "main_mode": { + "type": "string" + }, + "trip_weight": { + "type": "string" + }, + "short_walk_multiplier": { + "type": "string" + } + } + }, + "codes": { + "type": "object", + "additionalProperties": false, + "required": [ + "region", + "income_band", + "female", + "main_mode", + "frequency" + ], + "properties": { + "region": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "income_band": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "female": { + "type": "integer" + }, + "main_mode": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "frequency": { + "type": "object", + "additionalProperties": { + "type": "integer" + } + } + } + }, + "codebook_status": { + "type": "string" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "output", + "seed", + "n_estimators", + "predictors", + "categorical_predictors", + "income_band_edges", + "region_remap", + "trip_rates_resource", + "trip_rates_period_value", + "car_availability_resource", + "car_availability_period_value", + "fallback" + ], + "properties": { + "kind": { + "const": "impute_bus_use_band" + }, + "output": { + "type": "string" + }, + "seed": { + "type": "integer" + }, + "n_estimators": { + "type": "integer" + }, + "predictors": { + "type": "array", + "items": { + "type": "string" + } + }, + "categorical_predictors": { + "type": "array", + "items": { + "type": "string" + } + }, + "income_band_edges": { + "type": "array", + "items": { + "type": "number" + } + }, + "region_remap": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "trip_rates_resource": { + "type": "string" + }, + "trip_rates_period_value": { + "type": "integer" + }, + "car_availability_resource": { + "type": "string" + }, + "car_availability_period_value": { + "type": "integer" + }, + "fallback": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "period_value", + "share_geography", + "share_age_coverage", + "applied_to", + "transport_mode_groupby_value_id", + "older_age_band", + "age_threshold", + "user_definition", + "non_user_band", + "bands" + ], + "properties": { + "resource": { + "type": "string" + }, + "period_value": { + "type": "integer" + }, + "share_geography": { + "type": "string" + }, + "share_age_coverage": { + "enum": [ + "all_ages" + ] + }, + "applied_to": { + "enum": [ + "every_person" + ] + }, + "transport_mode_groupby_value_id": { + "type": "string" + }, + "older_age_band": { + "type": "string" + }, + "age_threshold": { + "type": "integer" + }, + "user_definition": { + "enum": [ + "at_least_once_a_year" + ] + }, + "non_user_band": { + "type": "string" + }, + "bands": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "id", + "trips_per_year", + "labels" + ], + "properties": { + "id": { + "type": "string" + }, + "trips_per_year": { + "type": "number" + }, + "labels": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "outputs", + "household_output", + "annualisation_weeks", + "trip_rates_resource", + "trip_rates_period_value", + "band_midpoints" + ], + "properties": { + "kind": { + "const": "assign_trips_from_band_means" + }, + "outputs": { + "type": "array", + "items": { + "type": "string" + } + }, + "household_output": { + "type": "string" + }, + "annualisation_weeks": { + "type": "number" + }, + "trip_rates_resource": { + "type": "string" + }, + "trip_rates_period_value": { + "type": "integer" + }, + "band_midpoints": { + "type": "object", + "additionalProperties": { + "type": "number" + } + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "output", + "basis", + "rules" + ], + "properties": { + "kind": { + "const": "assign_bus_pass_eligibility" + }, + "output": { + "type": "string" + }, + "basis": { + "type": "string" + }, + "rules": { + "type": "object", + "additionalProperties": { + "type": "object", + "additionalProperties": false, + "required": [ + "regions" + ], + "properties": { + "regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "min_age": { + "type": "integer" + }, + "max_age_exclusive": { + "type": "integer" + } + } + } + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "column", + "trips_columns", + "eligibility_column", + "fiscal_start", + "trip_rates_resource", + "trip_rates_period_value", + "population_resource", + "population_period_value", + "areas", + "unpriced_regions", + "scope_translation" + ], + "properties": { + "kind": { + "const": "price_bus_journeys" + }, + "column": { + "type": "string" + }, + "trips_columns": { + "type": "object", + "additionalProperties": false, + "required": [ + "bus_in_london", + "other_local_bus" + ], + "properties": { + "bus_in_london": { + "type": "string" + }, + "other_local_bus": { + "type": "string" + } + } + }, + "eligibility_column": { + "type": "string" + }, + "fiscal_start": { + "type": "string" + }, + "trip_rates_resource": { + "type": "string" + }, + "trip_rates_period_value": { + "type": "integer" + }, + "population_resource": { + "type": "string" + }, + "population_period_value": { + "type": "integer" + }, + "areas": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "label", + "series", + "receipts", + "boardings", + "concessionary", + "trips_concept", + "trips_basis", + "population_geography_ids" + ], + "properties": { + "label": { + "type": "string" + }, + "series": { + "enum": [ + "bus_in_london", + "other_local_bus" + ] + }, + "regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "receipts": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "boardings": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "concessionary": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "trips_concept": { + "type": "string" + }, + "trips_basis": { + "enum": [ + "published_series_rate", + "england_other_local_bus_rate_as_proxy" + ] + }, + "population_geography_ids": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + } + } + }, + "unpriced_regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "scope_translation": { + "type": "string" + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "support_column", + "trips_columns", + "eligibility_column", + "fiscal_start", + "trip_rates_resource", + "trip_rates_period_value", + "population_resource", + "population_period_value", + "pricing_areas", + "unpriced_regions", + "support_areas", + "basis" + ], + "properties": { + "kind": { + "const": "record_support_per_journey" + }, + "support_column": { + "type": "string" + }, + "trips_columns": { + "type": "object", + "additionalProperties": false, + "required": [ + "bus_in_london", + "other_local_bus" + ], + "properties": { + "bus_in_london": { + "type": "string" + }, + "other_local_bus": { + "type": "string" + } + } + }, + "eligibility_column": { + "type": "string" + }, + "fiscal_start": { + "type": "string" + }, + "trip_rates_resource": { + "type": "string" + }, + "trip_rates_period_value": { + "type": "integer" + }, + "population_resource": { + "type": "string" + }, + "population_period_value": { + "type": "integer" + }, + "pricing_areas": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "label", + "series", + "receipts", + "boardings", + "concessionary", + "trips_concept", + "trips_basis", + "population_geography_ids" + ], + "properties": { + "label": { + "type": "string" + }, + "series": { + "enum": [ + "bus_in_london", + "other_local_bus" + ] + }, + "regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "receipts": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "boardings": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "concessionary": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "trips_concept": { + "type": "string" + }, + "trips_basis": { + "enum": [ + "published_series_rate", + "england_other_local_bus_rate_as_proxy" + ] + }, + "population_geography_ids": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + } + } + }, + "unpriced_regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "support_areas": { + "type": "array", + "minItems": 1, + "items": { + "type": "object", + "additionalProperties": false, + "required": [ + "label", + "regions", + "reimbursement", + "net_support", + "boardings", + "concessionary" + ], + "properties": { + "label": { + "type": "string" + }, + "regions": { + "type": "array", + "items": { + "type": "string" + } + }, + "reimbursement": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "net_support": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "boardings": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + }, + "concessionary": { + "type": "object", + "additionalProperties": false, + "required": [ + "resource", + "concept" + ], + "properties": { + "resource": { + "type": "string" + }, + "concept": { + "type": "string" + }, + "geography_id": { + "type": "string" + }, + "groupby_value_id": { + "type": "string" + }, + "dimension_values": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "sum_over": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } + } + }, + "basis": { + "type": "string" + } + } } ], "description": "Closed kind-discriminated source artifact and operation records, covering the packaged US, UK, and BE source vocabularies." diff --git a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json index 4414145f0..863f42d4e 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json +++ b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json @@ -4,12 +4,13 @@ "kind": "uk_vendored_ledger_facts", "resource": "dft_bus_journeys.json", "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.lcfs_consumption", + "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", - "uk_runtime.bus_fare_pricing" + "uk_runtime.bus_support_per_journey" ], + "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", "generator": { "tool": "tools/vendor_uk_ledger_facts.py", diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index cfb761a3c..723367e29 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -141,6 +141,52 @@ }, "notes": "Stage-time support-clip health gate over the WAS wealth receipt; raw FRS mapping stages have no imputation semantics and intentionally have no empty health gate. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison." }, + { + "id": "uk_stage_nts_bus_travel_support", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "parameters": { + "stage": "nts_bus_travel", + "check": "support_clip", + "columns": [ + "bus_in_london_trips", + "local_bus_trips", + "local_bus_use_band", + "other_local_bus_trips" + ], + "max_clipped_low_rows_by_column": { + "bus_in_london_trips": 0, + "local_bus_trips": 0, + "local_bus_use_band": 0, + "other_local_bus_trips": 0 + }, + "max_clipped_high_rows_by_column": { + "bus_in_london_trips": 0, + "local_bus_trips": 0, + "local_bus_use_band": 0, + "other_local_bus_trips": 0 + } + }, + "notes": "Stage-time support-clip health gate over the NTS bus-travel receipt (microcosm#930): the band is an ordinal the QRF draws inside the donor's 0..6 and the trips are the donor's band means, so no row can clip; the zero allowances make any clip a signal." + }, + { + "id": "uk_stage_nts_bus_travel_facts", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "population_fact_check": true, + "parameters": { + "stage": "nts_bus_travel", + "check": "bus_travel_facts", + "trip_rates_period_value": 2024, + "maximum_user_share_deviation": 0.05, + "maximum_trip_rate_deviation": 0.15 + }, + "notes": "Stage-time fact check on the NTS bus-travel receipt (microcosm#930), every published value recomputed from the vendored rows: the frame's design-weighted share of persons who use a local bus at least yearly against the vendored NTS0313 all-ages share (maximum_user_share_deviation, in points), and the frame's mean local-bus trips per person per series against the vendored NTS0303 rate of the declared year (maximum_trip_rate_deviation, relative). The tolerances are rules set above what a conditional draw on the FRS composition can be expected to reproduce, not observed maxima; the stage runs on a synthetic donor in the smoke build, so the entry is a population fact check that a synthetic smoke records without blocking on. Car availability against NTS0205 is a receipt line, not a check: a mismatch there is a was_wealth finding." + }, { "id": "uk_stage_uc_deduction_attributes", "gate": "stage_health", @@ -222,7 +268,7 @@ "transport_consumption": 0 } }, - "notes": "Stage-time support-clip health gate over the LCFS receipt. The exempt energy columns are deliberately named here because they are bridged through the NEED/WAS path rather than clipped to LCFS donor support. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus fares are clipped before the fare rake (microcosm#890, María's ruling 2026-09-15): the clip bounds the regions no fare cell levels at donor support, the rake then moves the raked regions beyond it, and the column carries no committed terminal support bound." + "notes": "Stage-time support-clip health gate over the LCFS receipt. The exempt energy columns are deliberately named here because they are bridged through the NEED/WAS path rather than clipped to LCFS donor support. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus fares are clipped before the pricing step (microcosm#890 and #930, María's rulings 2026-09-15 and 2026-09-17): the clip bounds the region no area prices (Wales keeps the chain's raw draw) at donor support, the priced regions then move beyond it as journeys times the published yield, and the column carries no committed terminal support bound." }, { "id": "uk_stage_lcfs_consumption_energy_rake", @@ -246,6 +292,20 @@ }, "notes": "Stage-time energy check (microcosm#890 F, chronicle#270). María's ruling (2026-09-15, PR #927): 'I'm not sure why we are comparing against NEED as a gate in the first place if that is not what we are calibrating, but I agree we should implement Vahid's recommended fix and move the fix to before calibration.' Fact checks on the lcfs energy_rake receipt, every published value recomputed at gate time from the vendored rows the stage declares: each cell's shape target is the vendored NEED 2024 mean (need_energy_facts.json, margins_period_value), each fuel's level is the vendored DESNZ Energy Trends domestic consumption at actual temperature over the four FY2024-25 quarters (desnz_domestic_energy_facts.json) with the level factor equal to that total over the frame's pre-level total and the levelled frame total equal to the published one, each cell's target is shape times factor, and every region with a published gas-connected share (DESNZ subnational gas meters over electricity meters, 2024) sits within 0.5 points of it after the imposition unless the draw could not fill it (a receipted shortfall). The residual check holds the maximum absolute relative deviation of any cell mean from its levelled target, per margin (income band, tenure, property type, region) and fuel, electricity over every household of a cell and gas over its gas-connected households, to one fixed 2.5 % tolerance on the IPF's cross-margin residual (region is swept last and fits to machine precision by construction, so the tolerance binds the earlier three; a declared rule set above the observed maxima, not a fact: spine-s3 on NEED 2023 showed income 1.65 %, tenure 1.29 %, accommodation 0.83 %; spine-s5 on the NEED 2024 shape with the published connection showed income 2.16 % electricity / 1.97 % gas, accommodation 1.46 %, tenure 1.31 %, which is why the 2 % rule of spine-s3 moved to 2.5 %). This gate replaced the two NEED mean-spend anchors that uk_aggregate_admin measured on the calibrated frame; the calibrated frame is held to the bound ONS 04.5.1 electricity and 04.5.2 gas rows, and the gap between the DESNZ-volume-times-QEP-price level the stage sets and the ONS national-accounts spend is the published-source residual PR #927 receipts Part T records, not a gate. The entry is a population_fact_check: a synthetic smoke build (the staging smoke over the H2 fixture) records its outcome without blocking, because the fixture is not the population NEED, DESNZ and the meter counts describe; every licensed build blocks on it. Tolerance governance (Vahid's third pass on PR #927): maximum_relative_deviation is a rule set above the observed maxima, not a fact; the rake runs a fixed number of sweeps and the receipt now records the cross-margin residual after every sweep (sweep_residuals), so the terminal residual is shown converged, not truncated, and a vintage whose converged residual exceeds the rule is a new ruling for María, never a silent re-pin. maximum_connected_share_deviation is declared, not derived from the walk: the greedy weight-fitting walk lands within a fraction of one household weight of the published share, and the check is waived only for a region whose draw cannot fill its published share (the shortfall is receipted and reported here), never for a region above it. The regions the crosswalk maps to no subnational area are declared on the stage (connection_fallback_regions, Northern Ireland) and refused if they differ from the crosswalk." }, + { + "id": "uk_stage_lcfs_consumption_bus_pricing", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "population_fact_check": true, + "parameters": { + "stage": "lcfs_consumption", + "check": "bus_pricing", + "maximum_relative_deviation": 1e-09 + }, + "notes": "Stage-time fact check on the lcfs bus_pricing receipt (microcosm#930): every area's receipts, boardings, concessionary journeys, trips per resident and population, and the boardings-per-trip and yield factors derived from them, are recomputed from the vendored rows the stage declares and must equal the receipt's; the unpriced regions must be the declared ones (Wales, which keeps the chain's raw draw by María's ruling of 2026-09-17) and the chain must have conditioned on the raw draw. The frame-implied boardings over the published ones are reported per area, not fenced: that ratio is the survey-versus-admin reading the bound receipts targets then act on. A population fact check: the synthetic smoke records it without blocking." + }, { "id": "uk_stage_etb_vat_support", "gate": "stage_health", @@ -295,6 +355,27 @@ }, "notes": "Stage-time support-clip health gate over the ETB services receipt. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus support is exempt since microcosm#890: the declared rake to the published net support sets its level." }, + { + "id": "uk_stage_etb_services_support_rake", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "population_fact_check": true, + "parameters": { + "stage": "etb_services", + "check": "fact_rake", + "receipt_key": "bus_support_rake", + "maximum_relative_deviation": 1e-06, + "allowed_resources": [ + "orr_rail_facts.json", + "dft_bus_value_anchors.json", + "devolved_bus_finance.json", + "dft_bus_journeys.json" + ] + }, + "notes": "Stage-time fact check on the ETB bus-support rake receipt (microcosm#930 C7; the #890 rake had no fence): every cell's published net support (DfT BUS05bi for London and England outside London, Scottish Transport Statistics, StatsWales, and the NITHC bus-plus-rail joint cell) is recomputed from the vendored rows through the stage's own declaration and must equal the receipt's, and each cell's design-weighted total after the rake must equal its published value (a joint cell over the sum of its columns); a skipped cell fails closed. A population fact check: the synthetic smoke records it without blocking. The stage also records, unfenced, what pricing support from the frame's journeys would give (support_per_journey), for María's ruling on retiring this rake." + }, { "id": "uk_stage_frs_hmrc_spine_leaves_signal", "gate": "stage_health", @@ -639,6 +720,7 @@ "household.household_is_capital_gains_clone", "household.household_is_cgt_band_donor", "household.household_is_spi_synthetic", + "household.household_local_bus_trips", "household.la_code_oa", "household.local_authority", "household.lsoa_code", @@ -659,6 +741,8 @@ "person.attends_private_school_random_draw", "person.capital_gains_asset_type", "person.capital_gains_residential_property", + "person.bus_in_london_trips", + "person.bus_pass_eligible", "person.care_hours", "person.charitable_investment_gifts", "person.dla_m_category", @@ -673,8 +757,11 @@ "person.is_parent", "person.is_uc_claimant", "person.legacy_jobseeker_proxy", + "person.local_bus_trips", + "person.local_bus_use_band", "person.ons_family_index", "person.ons_family_role", + "person.other_local_bus_trips", "person.outpatient_visits", "person.pension_contributions_via_salary_sacrifice", "person.pip_dl_category", diff --git a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json index 7fd1519f2..059c8cd7a 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json @@ -235,8 +235,8 @@ "resource": "nts_bus_use_frequency.json", "purpose": "DfT NTS0313 shares of people by frequency of local bus use (all ages, England) and NTS0621 the same bands for people aged 60 and over, 2023 to 2025, with the unweighted sample sizes. Consumed by the LCFS bus-use incidence calibration.", "consumers": [ - "uk_runtime.lcfs_consumption", - "uk_runtime.bus_use_incidence" + "uk_runtime.bus_use_incidence", + "uk_runtime.nts_bus_travel" ], "planned_consumers": [], "selections": [ @@ -584,12 +584,13 @@ { "resource": "dft_bus_journeys.json", "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.lcfs_consumption", + "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", - "uk_runtime.bus_fare_pricing" + "uk_runtime.bus_support_per_journey" ], + "planned_consumers": [], "selections": [ { "label": "bus01a_passenger_journeys_by_area", @@ -710,10 +711,10 @@ { "resource": "nts_trip_rates.json", "purpose": "DfT NTS0303 average trips per person per year by main mode (all modes, bus in London, other local bus; England, all ages) and NTS0601 the same rates by age band, survey years 2023 to 2025. Consumed by the NTS bus-travel stage's fact checks on the imputed trip rates by age and the level of local-bus trips per resident (microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.nts_bus_travel" ], + "planned_consumers": [], "selections": [ { "label": "nts0303_trips_per_person_by_mode", @@ -758,10 +759,10 @@ { "resource": "nts_car_availability.json", "purpose": "DfT NTS0205 shares of households with no car or van, one, and two or more (England, survey years 2023 and 2024). Consumed by the NTS bus-travel stage's receipt of the frame's num_vehicles distribution against the published shares (microcosm#890 item A, carried by microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.nts_bus_travel" ], + "planned_consumers": [], "selections": [ { "label": "nts0205_household_car_availability_england", diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json index 6612d3f57..e39dcb8ee 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_use_frequency.json @@ -5,8 +5,8 @@ "resource": "nts_bus_use_frequency.json", "purpose": "DfT NTS0313 shares of people by frequency of local bus use (all ages, England) and NTS0621 the same bands for people aged 60 and over, 2023 to 2025, with the unweighted sample sizes. Consumed by the LCFS bus-use incidence calibration.", "consumers": [ - "uk_runtime.lcfs_consumption", - "uk_runtime.bus_use_incidence" + "uk_runtime.bus_use_incidence", + "uk_runtime.nts_bus_travel" ], "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json b/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json index 3c35d9722..a9f159c37 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_car_availability.json @@ -4,10 +4,10 @@ "kind": "uk_vendored_ledger_facts", "resource": "nts_car_availability.json", "purpose": "DfT NTS0205 shares of households with no car or van, one, and two or more (England, survey years 2023 and 2024). Consumed by the NTS bus-travel stage's receipt of the frame's num_vehicles distribution against the published shares (microcosm#890 item A, carried by microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.nts_bus_travel" ], + "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", "generator": { "tool": "tools/vendor_uk_ledger_facts.py", diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json b/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json index 23bef790e..027e4ece1 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_trip_rates.json @@ -4,10 +4,10 @@ "kind": "uk_vendored_ledger_facts", "resource": "nts_trip_rates.json", "purpose": "DfT NTS0303 average trips per person per year by main mode (all modes, bus in London, other local bus; England, all ages) and NTS0601 the same rates by age band, survey years 2023 to 2025. Consumed by the NTS bus-travel stage's fact checks on the imputed trip rates by age and the level of local-bus trips per resident (microcosm#930).", - "consumers": [], - "planned_consumers": [ + "consumers": [ "uk_runtime.nts_bus_travel" ], + "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", "generator": { "tool": "tools/vendor_uk_ledger_facts.py", 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 d89af16eb..261edec79 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1438,6 +1438,334 @@ ], "notes": "Deterministically rescales owner rows so regional unweighted owner means match the public house-price reference. Northern Ireland has no reference row and is never scaled; empty and nonpositive regions are skipped. The unweighted mean follows the incumbent behavior." }, + { + "stage": "nts_bus_travel", + "survey": "National Travel Survey 2002-2024", + "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.", + "grain": "person", + "artifacts": [ + { + "role": "nts_household_tab", + "kind": "private_microdata", + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "household_eul_2002-2024.tab", + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "access": "private_local_input", + "locator": "caller-supplied local input", + "runtime_sha256_required": true + }, + { + "role": "nts_individual_tab", + "kind": "private_microdata", + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "individual_eul_2002-2024.tab", + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "access": "private_local_input", + "locator": "caller-supplied local input", + "runtime_sha256_required": true + }, + { + "role": "nts_trip_tab", + "kind": "private_microdata", + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "trip_eul_2002-2024.tab", + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "access": "private_local_input", + "locator": "caller-supplied local input", + "runtime_sha256_required": true + }, + { + "role": "nts_trip_rates", + "resource": "nts_trip_rates.json", + "kind": "public_aggregate_reference", + "format": "json" + }, + { + "role": "nts_car_availability", + "resource": "nts_car_availability.json", + "kind": "public_aggregate_reference", + "format": "json" + }, + { + "role": "nts_bus_use_frequency", + "resource": "nts_bus_use_frequency.json", + "kind": "public_aggregate_reference", + "format": "json" + } + ], + "operations": [ + { + "kind": "clean_nts_travel_tables", + "lowercase_columns": true, + "survey_years": [ + 2022, + 2023, + 2024 + ], + "cars_clip": [ + 0, + 5 + ], + "age_band_edges": [ + 0, + 5, + 11, + 17, + 21, + 30, + 40, + 50, + 60, + 70 + ], + "columns": { + "household_id": "HouseholdID", + "individual_id": "IndividualID", + "trip_id": "TripID", + "survey_year": "SurveyYear", + "region": "HHoldGOR_B02ID", + "income_band": "HHIncome2002_B02ID", + "cars": "NumCarVan", + "household_size": "HHoldNumPeople", + "household_weight": "W2", + "age_band": "Age_B01ID", + "sex": "Sex_B01ID", + "frequency": "LocalBusFreq_B01ID", + "main_mode": "MainMode_B04ID", + "trip_weight": "W5xHH", + "short_walk_multiplier": "JJXSC" + }, + "codes": { + "region": { + "1": "NORTH_EAST", + "2": "NORTH_WEST", + "3": "YORKSHIRE", + "4": "EAST_MIDLANDS", + "5": "WEST_MIDLANDS", + "6": "EAST_OF_ENGLAND", + "7": "LONDON", + "8": "SOUTH_EAST", + "9": "SOUTH_WEST" + }, + "income_band": { + "1": 1, + "2": 2, + "3": 3 + }, + "female": 2, + "main_mode": { + "bus_in_london": 7, + "other_local_bus": 8 + }, + "frequency": { + "1": 6, + "2": 5, + "3": 4, + "4": 3, + "5": 2, + "6": 1, + "7": 0 + } + }, + "codebook_status": "declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback" + }, + { + "kind": "materialize_rules_engine_predictors", + "predictors": [ + "household_gross_income" + ], + "consumed_only": true + }, + { + "kind": "impute_bus_use_band", + "output": "local_bus_use_band", + "seed": 0, + "n_estimators": 100, + "predictors": [ + "age_band", + "is_female", + "num_vehicles", + "household_size", + "income_band", + "region" + ], + "categorical_predictors": [ + "region" + ], + "income_band_edges": [ + 25000, + 50000 + ], + "region_remap": { + "SCOTLAND": "NORTH_EAST", + "WALES": "SOUTH_WEST", + "NORTHERN_IRELAND": "NORTH_EAST" + }, + "trip_rates_resource": "nts_trip_rates.json", + "trip_rates_period_value": 2024, + "car_availability_resource": "nts_car_availability.json", + "car_availability_period_value": 2024, + "fallback": { + "resource": "nts_bus_use_frequency.json", + "period_value": 2024, + "share_geography": "E92000001", + "share_age_coverage": "all_ages", + "applied_to": "every_person", + "transport_mode_groupby_value_id": "local_bus", + "older_age_band": "60 and over", + "age_threshold": 60, + "user_definition": "at_least_once_a_year", + "non_user_band": "less_than_once_a_year_or_never", + "bands": [ + { + "id": "three_or_more_times_a_week", + "trips_per_year": 208, + "labels": [ + "3 or more times a week (%)" + ] + }, + { + "id": "once_or_twice_a_week", + "trips_per_year": 78, + "labels": [ + "Once or twice a week (%)" + ] + }, + { + "id": "less_than_weekly_more_than_twice_a_month", + "trips_per_year": 36, + "labels": [ + "Less than once a week, more than once or twice a month (%)", + "Less than once per week, more than twice a month (%)" + ] + }, + { + "id": "once_or_twice_a_month", + "trips_per_year": 18, + "labels": [ + "Once or twice a month (%)" + ] + }, + { + "id": "less_than_monthly_more_than_twice_a_year", + "trips_per_year": 6, + "labels": [ + "Less than once a month, more than once or twice a year (%)", + "Less than once a month, more than twice a year (%)" + ] + }, + { + "id": "once_or_twice_a_year", + "trips_per_year": 1.5, + "labels": [ + "Once or twice a year (%)" + ] + }, + { + "id": "less_than_once_a_year_or_never", + "trips_per_year": 0, + "labels": [ + "Less than once a year or never (%)" + ] + } + ] + } + }, + { + "kind": "assign_trips_from_band_means", + "outputs": [ + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips" + ], + "household_output": "household_local_bus_trips", + "annualisation_weeks": 52.14, + "trip_rates_resource": "nts_trip_rates.json", + "trip_rates_period_value": 2024, + "band_midpoints": { + "three_or_more_times_a_week": 208, + "once_or_twice_a_week": 78, + "less_than_weekly_more_than_twice_a_month": 36, + "once_or_twice_a_month": 18, + "less_than_monthly_more_than_twice_a_year": 6, + "once_or_twice_a_year": 1.5, + "less_than_once_a_year_or_never": 0 + } + }, + { + "kind": "assign_bus_pass_eligibility", + "output": "bus_pass_eligible", + "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield", + "rules": { + "england_outside_london": { + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST" + ], + "min_age": 66 + }, + "london": { + "regions": [ + "LONDON" + ], + "min_age": 60, + "max_age_exclusive": 18 + }, + "scotland": { + "regions": [ + "SCOTLAND" + ], + "min_age": 60, + "max_age_exclusive": 22 + }, + "wales": { + "regions": [ + "WALES" + ], + "min_age": 60 + }, + "northern_ireland": { + "regions": [ + "NORTHERN_IRELAND" + ], + "min_age": 65 + } + } + }, + { + "kind": "support_clip", + "range": "donor_realized" + } + ], + "outputs": [ + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + "bus_pass_eligible", + "household_local_bus_trips" + ], + "nonnegative_outputs": [ + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + "household_local_bus_trips" + ], + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed." + }, { "stage": "lcfs_consumption", "survey": "Living Costs and Food Survey 2023-24", @@ -1509,8 +1837,8 @@ "format": "json" }, { - "role": "nts_bus_use_frequency", - "resource": "nts_bus_use_frequency.json", + "role": "dft_bus_journeys", + "resource": "dft_bus_journeys.json", "kind": "public_aggregate_reference", "format": "json" }, @@ -1676,74 +2004,6 @@ "condition": "num_vehicles > 0", "seed": 0 }, - { - "kind": "assign_bus_use_incidence", - "output": "uses_local_bus", - "seed": 0, - "resource": "nts_bus_use_frequency.json", - "period_value": 2024, - "share_geography": "E92000001", - "share_age_coverage": "all_ages", - "applied_to": "fare_rake_regions", - "transport_mode_groupby_value_id": "local_bus", - "older_age_band": "60 and over", - "age_threshold": 60, - "user_definition": "at_least_once_a_year", - "non_user_band": "less_than_once_a_year_or_never", - "bands": [ - { - "id": "three_or_more_times_a_week", - "trips_per_year": 208, - "labels": [ - "3 or more times a week (%)" - ] - }, - { - "id": "once_or_twice_a_week", - "trips_per_year": 78, - "labels": [ - "Once or twice a week (%)" - ] - }, - { - "id": "less_than_weekly_more_than_twice_a_month", - "trips_per_year": 36, - "labels": [ - "Less than once a week, more than once or twice a month (%)", - "Less than once per week, more than twice a month (%)" - ] - }, - { - "id": "once_or_twice_a_month", - "trips_per_year": 18, - "labels": [ - "Once or twice a month (%)" - ] - }, - { - "id": "less_than_monthly_more_than_twice_a_year", - "trips_per_year": 6, - "labels": [ - "Less than once a month, more than once or twice a year (%)", - "Less than once a month, more than twice a year (%)" - ] - }, - { - "id": "once_or_twice_a_year", - "trips_per_year": 1.5, - "labels": [ - "Once or twice a year (%)" - ] - }, - { - "id": "less_than_once_a_year_or_never", - "trips_per_year": 0, - "labels": [ - "Less than once a year or never (%)" - ] - } - ] - }, { "kind": "materialize_rules_engine_predictors", "predictors": [ @@ -1852,33 +2112,57 @@ "level_temperature_adjustment": "actual_temperature" }, { - "kind": "rake_to_vendored_facts", - "columns": [ - "bus_fare_spending" - ], - "scope": "users_only", - "quintile_income": "hbai_household_net_income", - "iterations": 1, - "weighted": true, - "cells": [ + "kind": "price_bus_journeys", + "column": "bus_fare_spending", + "trips_columns": { + "bus_in_london": "bus_in_london_trips", + "other_local_bus": "other_local_bus_trips" + }, + "eligibility_column": "bus_pass_eligible", + "fiscal_start": "2024-04-01", + "trip_rates_resource": "dft_bus_value_anchors.json", + "trip_rates_period_value": 2024, + "population_resource": "dft_bus_journeys.json", + "population_period_value": 2024, + "areas": [ { "label": "london", - "regions": [ - "LONDON" - ], - "resource": "dft_bus_value_anchors.json", - "selector": { + "series": "bus_in_london", + "receipts": { + "resource": "dft_bus_value_anchors.json", "concept": "dft.local_bus_passenger_fare_receipts", - "fiscal_start": "2024-04-01", "geography_id": "E12000007" }, - "allocation": "income_quintile_trips", - "allocation_resource": "dft_bus_value_anchors.json", - "allocation_concept": "dft.bus_in_london_trips_per_person", - "allocation_period_value": 2024 + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "dimension_values": { + "journey_category": "total_concessionary" + } + }, + "trips_concept": "dft.bus_in_london_trips_per_person", + "trips_basis": "published_series_rate", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ] }, { "label": "england_outside_london", + "series": "other_local_bus", "regions": [ "NORTH_EAST", "NORTH_WEST", @@ -1886,52 +2170,120 @@ "EAST_MIDLANDS", "WEST_MIDLANDS", "EAST_OF_ENGLAND", + "LONDON", "SOUTH_EAST", "SOUTH_WEST" ], - "resource": "dft_bus_value_anchors.json", - "selector": { + "receipts": { + "resource": "dft_bus_value_anchors.json", "concept": "dft.local_bus_passenger_fare_receipts", - "fiscal_start": "2024-04-01", "geography_id": "dft:england_outside_london" }, - "allocation": "income_quintile_trips", - "allocation_resource": "dft_bus_value_anchors.json", - "allocation_concept": "dft.other_local_bus_trips_per_person", - "allocation_period_value": 2024 + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "dimension_values": { + "journey_category": "total_concessionary" + } + }, + "trips_concept": "dft.other_local_bus_trips_per_person", + "trips_basis": "published_series_rate", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ] }, { "label": "scotland", + "series": "other_local_bus", "regions": [ "SCOTLAND" ], - "resource": "devolved_bus_finance.json", - "selector": { + "receipts": { + "resource": "devolved_bus_finance.json", "concept": "scotgov.bus.operator_revenue", - "fiscal_start": "2024-04-01", - "groupby_value_id": "passenger_revenue" + "groupby_value_id": "passenger_revenue", + "dimension_values": { + "revenue_component": "passenger_revenue" + } }, - "allocation": "uniform" + "boardings": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys" + }, + "concessionary": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "concessionary_passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + } + }, + "trips_concept": "dft.other_local_bus_trips_per_person", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "population_geography_ids": [ + "S92000003" + ] }, { "label": "northern_ireland", + "series": "other_local_bus", "regions": [ "NORTHERN_IRELAND" ], - "resource": "devolved_bus_finance.json", - "selector": { + "receipts": { + "resource": "devolved_bus_finance.json", "concept": "dfi_ni.translink_bus.passenger_receipts", - "fiscal_start": "2024-04-01", "sum_over": { "service": [ - "ulsterbus", - "metro_glider" + "metro_glider", + "ulsterbus" ] } }, - "allocation": "uniform" + "boardings": { + "resource": "devolved_bus_finance.json", + "concept": "dfi_ni.translink_bus.passenger_journeys", + "sum_over": { + "service": [ + "metro_glider", + "ulsterbus" + ] + } + }, + "concessionary": { + "resource": "devolved_bus_finance.json", + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "dimension_values": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + } + }, + "trips_concept": "dft.other_local_bus_trips_per_person", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "population_geography_ids": [ + "N92000002" + ] } - ] + ], + "unpriced_regions": [ + "WALES" + ], + "scope_translation": "operator receipts carry interchange boardings, non-resident and business payers, and London contactless is not separated, so the yield is per resident trip, not a fare; Wales publishes journeys but no receipts and keeps the chain's raw draw clipped to donor support" }, { "kind": "fold_into", @@ -2000,7 +2352,7 @@ "gas_consumption", "has_fuel_consumption" ], - "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level." + "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the pricing step (María's rulings 2026-09-15 and 2026-09-17), which bounds the region no area prices (Wales keeps the chain's raw draw) while the priced regions move beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Bus fares are priced from journeys (microcosm#930), where the nts_bus_travel stage imputes each person's annual bus-in-London and other-local-bus trips and their concessionary eligibility, and the declared price_bus_journeys step sets bus_fare_spending as the sum over the household's non-eligible persons of trips times boardings per resident trip (the published BUS01 journeys over the published NTS0705a trips per resident times the ONS population) times the yield per fare-paying boarding (BUS05ai receipts over journeys less concessionary journeys), per area; bus-in-London trips take the London area's price for every resident, other-local-bus trips the price of the residence area (England outside London; Scotland and Northern Ireland from their own receipts and journeys with England's trip rate as the declared proxy); Wales is unpriced and keeps the raw draw. The chain still draws bus_fare_spending so later targets condition on the same raw draw; the emitted column is the priced value. The receipt records every factor, the frame-implied boardings beside the published ones and the frame's eligible trip share beside the publisher's concessionary boarding share, so the design-weight fit of the bound receipts targets is read as a composition check, never a level the stage set; the" }, { "stage": "etb_vat", @@ -2135,6 +2487,12 @@ "resource": "devolved_bus_finance.json", "kind": "public_aggregate_reference", "format": "json" + }, + { + "role": "dft_bus_journeys", + "resource": "dft_bus_journeys.json", + "kind": "public_aggregate_reference", + "format": "json" } ], "operations": [ @@ -2321,6 +2679,176 @@ } ] }, + { + "kind": "record_support_per_journey", + "support_column": "bus_subsidy_spending", + "trips_columns": { + "bus_in_london": "bus_in_london_trips", + "other_local_bus": "other_local_bus_trips" + }, + "eligibility_column": "bus_pass_eligible", + "fiscal_start": "2024-04-01", + "trip_rates_resource": "dft_bus_value_anchors.json", + "trip_rates_period_value": 2024, + "population_resource": "dft_bus_journeys.json", + "population_period_value": 2024, + "pricing_areas": [ + { + "label": "london", + "series": "bus_in_london", + "receipts": { + "resource": "dft_bus_value_anchors.json", + "concept": "dft.local_bus_passenger_fare_receipts", + "geography_id": "E12000007" + }, + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "dimension_values": { + "journey_category": "total_concessionary" + } + }, + "trips_concept": "dft.bus_in_london_trips_per_person", + "trips_basis": "published_series_rate", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ] + }, + { + "label": "england_outside_london", + "series": "other_local_bus", + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST", + "LONDON" + ], + "receipts": { + "resource": "dft_bus_value_anchors.json", + "concept": "dft.local_bus_passenger_fare_receipts", + "geography_id": "dft:england_outside_london" + }, + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "dimension_values": { + "journey_category": "total_concessionary" + } + }, + "trips_concept": "dft.other_local_bus_trips_per_person", + "trips_basis": "published_series_rate", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ] + } + ], + "unpriced_regions": [ + "SCOTLAND", + "WALES", + "NORTHERN_IRELAND" + ], + "support_areas": [ + { + "label": "london", + "regions": [ + "LONDON" + ], + "reimbursement": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "geography_id": "E12000007" + }, + "net_support": { + "resource": "dft_bus_value_anchors.json", + "concept": "dft.local_bus_total_estimated_net_support", + "geography_id": "E12000007" + }, + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "dimension_values": { + "journey_category": "total_concessionary" + } + } + }, + { + "label": "england_outside_london", + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST" + ], + "reimbursement": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "geography_id": "dft:england_outside_london" + }, + "net_support": { + "resource": "dft_bus_value_anchors.json", + "concept": "dft.local_bus_total_estimated_net_support", + "geography_id": "dft:england_outside_london" + }, + "boardings": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london" + }, + "concessionary": { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "dimension_values": { + "journey_category": "total_concessionary" + } + } + } + ], + "basis": "value-side alternative recorded beside the raked column, never applied (microcosm#930, María's ruling pending); England only, where DfT publishes the reimbursement and net support by area" + }, { "kind": "compute_ratio", "output": "rail_usage", 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 0aab2000c..6f597e910 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1088,6 +1088,254 @@ stages: - main_residence_value - property_wealth notes: Deterministically rescales owner rows so regional unweighted owner means match the public house-price reference. Northern Ireland has no reference row and is never scaled; empty and nonpositive regions are skipped. The unweighted mean follows the incumbent behavior. +- stage: nts_bus_travel + survey: National Travel Survey 2002-2024 + 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. + grain: person + artifacts: + - role: nts_household_tab + kind: private_microdata + ukds_study_number: 5340 + doi: 10.5255/UKDA-SN-5340-19 + filename: household_eul_2002-2024.tab + sha256: '0000000000000000000000000000000000000000000000000000000000000000' + size_bytes: 0 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true + - role: nts_individual_tab + kind: private_microdata + ukds_study_number: 5340 + doi: 10.5255/UKDA-SN-5340-19 + filename: individual_eul_2002-2024.tab + sha256: '0000000000000000000000000000000000000000000000000000000000000000' + size_bytes: 0 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true + - role: nts_trip_tab + kind: private_microdata + ukds_study_number: 5340 + doi: 10.5255/UKDA-SN-5340-19 + filename: trip_eul_2002-2024.tab + sha256: '0000000000000000000000000000000000000000000000000000000000000000' + size_bytes: 0 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true + - role: nts_trip_rates + resource: nts_trip_rates.json + kind: public_aggregate_reference + format: json + - role: nts_car_availability + resource: nts_car_availability.json + kind: public_aggregate_reference + format: json + - role: nts_bus_use_frequency + resource: nts_bus_use_frequency.json + kind: public_aggregate_reference + format: json + operations: + - kind: clean_nts_travel_tables + lowercase_columns: true + survey_years: + - 2022 + - 2023 + - 2024 + cars_clip: + - 0 + - 5 + age_band_edges: + - 0 + - 5 + - 11 + - 17 + - 21 + - 30 + - 40 + - 50 + - 60 + - 70 + columns: + household_id: HouseholdID + individual_id: IndividualID + trip_id: TripID + survey_year: SurveyYear + region: HHoldGOR_B02ID + income_band: HHIncome2002_B02ID + cars: NumCarVan + household_size: HHoldNumPeople + household_weight: W2 + age_band: Age_B01ID + sex: Sex_B01ID + frequency: LocalBusFreq_B01ID + main_mode: MainMode_B04ID + trip_weight: W5xHH + short_walk_multiplier: JJXSC + codes: + region: + '1': NORTH_EAST + '2': NORTH_WEST + '3': YORKSHIRE + '4': EAST_MIDLANDS + '5': WEST_MIDLANDS + '6': EAST_OF_ENGLAND + '7': LONDON + '8': SOUTH_EAST + '9': SOUTH_WEST + income_band: + '1': 1 + '2': 2 + '3': 3 + female: 2 + main_mode: + bus_in_london: 7 + other_local_bus: 8 + frequency: + '1': 6 + '2': 5 + '3': 4 + '4': 3 + '5': 2 + '6': 1 + '7': 0 + codebook_status: declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback + - kind: materialize_rules_engine_predictors + predictors: + - household_gross_income + consumed_only: true + - kind: impute_bus_use_band + output: local_bus_use_band + seed: 0 + n_estimators: 100 + predictors: + - age_band + - is_female + - num_vehicles + - household_size + - income_band + - region + categorical_predictors: + - region + income_band_edges: + - 25000 + - 50000 + region_remap: + SCOTLAND: NORTH_EAST + WALES: SOUTH_WEST + NORTHERN_IRELAND: NORTH_EAST + trip_rates_resource: nts_trip_rates.json + trip_rates_period_value: 2024 + car_availability_resource: nts_car_availability.json + car_availability_period_value: 2024 + fallback: + resource: nts_bus_use_frequency.json + period_value: 2024 + share_geography: E92000001 + share_age_coverage: all_ages + applied_to: every_person + transport_mode_groupby_value_id: local_bus + older_age_band: 60 and over + age_threshold: 60 + user_definition: at_least_once_a_year + non_user_band: less_than_once_a_year_or_never + bands: + - id: three_or_more_times_a_week + trips_per_year: 208 + labels: + - 3 or more times a week (%) + - id: once_or_twice_a_week + trips_per_year: 78 + labels: + - Once or twice a week (%) + - id: less_than_weekly_more_than_twice_a_month + trips_per_year: 36 + labels: + - Less than once a week, more than once or twice a month (%) + - Less than once per week, more than twice a month (%) + - id: once_or_twice_a_month + trips_per_year: 18 + labels: + - Once or twice a month (%) + - id: less_than_monthly_more_than_twice_a_year + trips_per_year: 6 + labels: + - Less than once a month, more than once or twice a year (%) + - Less than once a month, more than twice a year (%) + - id: once_or_twice_a_year + trips_per_year: 1.5 + labels: + - Once or twice a year (%) + - id: less_than_once_a_year_or_never + trips_per_year: 0 + labels: + - Less than once a year or never (%) + - kind: assign_trips_from_band_means + outputs: + - bus_in_london_trips + - other_local_bus_trips + - local_bus_trips + household_output: household_local_bus_trips + annualisation_weeks: 52.14 + trip_rates_resource: nts_trip_rates.json + trip_rates_period_value: 2024 + band_midpoints: + three_or_more_times_a_week: 208 + once_or_twice_a_week: 78 + less_than_weekly_more_than_twice_a_month: 36 + once_or_twice_a_month: 18 + less_than_monthly_more_than_twice_a_year: 6 + once_or_twice_a_year: 1.5 + less_than_once_a_year_or_never: 0 + - kind: assign_bus_pass_eligibility + output: bus_pass_eligible + basis: statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield + rules: + england_outside_london: + regions: + - NORTH_EAST + - NORTH_WEST + - YORKSHIRE + - EAST_MIDLANDS + - WEST_MIDLANDS + - EAST_OF_ENGLAND + - SOUTH_EAST + - SOUTH_WEST + min_age: 66 + london: + regions: + - LONDON + min_age: 60 + max_age_exclusive: 18 + scotland: + regions: + - SCOTLAND + min_age: 60 + max_age_exclusive: 22 + wales: + regions: + - WALES + min_age: 60 + northern_ireland: + regions: + - NORTHERN_IRELAND + min_age: 65 + - kind: support_clip + range: donor_realized + outputs: + - local_bus_use_band + - bus_in_london_trips + - other_local_bus_trips + - local_bus_trips + - bus_pass_eligible + - household_local_bus_trips + nonnegative_outputs: + - local_bus_use_band + - bus_in_london_trips + - other_local_bus_trips + - local_bus_trips + - household_local_bus_trips + notes: Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed. - stage: lcfs_consumption survey: Living Costs and Food Survey 2023-24 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. @@ -1140,8 +1388,8 @@ stages: resource: licensed_cars_fuel_type.json kind: public_aggregate_reference format: json - - role: nts_bus_use_frequency - resource: nts_bus_use_frequency.json + - role: dft_bus_journeys + resource: dft_bus_journeys.json kind: public_aggregate_reference format: json - role: dft_bus_value_anchors @@ -1264,50 +1512,6 @@ stages: - fuel_cell_electric condition: num_vehicles > 0 seed: 0 - - kind: assign_bus_use_incidence - output: uses_local_bus - seed: 0 - resource: nts_bus_use_frequency.json - period_value: 2024 - share_geography: E92000001 - share_age_coverage: all_ages - applied_to: fare_rake_regions - transport_mode_groupby_value_id: local_bus - older_age_band: 60 and over - age_threshold: 60 - user_definition: at_least_once_a_year - non_user_band: less_than_once_a_year_or_never - bands: - - id: three_or_more_times_a_week - trips_per_year: 208 - labels: - - 3 or more times a week (%) - - id: once_or_twice_a_week - trips_per_year: 78 - labels: - - Once or twice a week (%) - - id: less_than_weekly_more_than_twice_a_month - trips_per_year: 36 - labels: - - Less than once a week, more than once or twice a month (%) - - Less than once per week, more than twice a month (%) - - id: once_or_twice_a_month - trips_per_year: 18 - labels: - - Once or twice a month (%) - - id: less_than_monthly_more_than_twice_a_year - trips_per_year: 6 - labels: - - Less than once a month, more than once or twice a year (%) - - Less than once a month, more than twice a year (%) - - id: once_or_twice_a_year - trips_per_year: 1.5 - labels: - - Once or twice a year (%) - - id: less_than_once_a_year_or_never - trips_per_year: 0 - labels: - - Less than once a year or never (%) - kind: materialize_rules_engine_predictors predictors: - is_adult @@ -1396,27 +1600,48 @@ stages: level_resource: desnz_domestic_energy_facts.json level_fiscal_start: '2024-04-01' level_temperature_adjustment: actual_temperature - - kind: rake_to_vendored_facts - columns: - - bus_fare_spending - scope: users_only - quintile_income: hbai_household_net_income - iterations: 1 - weighted: true - cells: + - kind: price_bus_journeys + column: bus_fare_spending + trips_columns: + bus_in_london: bus_in_london_trips + other_local_bus: other_local_bus_trips + eligibility_column: bus_pass_eligible + fiscal_start: '2024-04-01' + trip_rates_resource: dft_bus_value_anchors.json + trip_rates_period_value: 2024 + population_resource: dft_bus_journeys.json + population_period_value: 2024 + areas: - label: london - regions: - - LONDON - resource: dft_bus_value_anchors.json - selector: + series: bus_in_london + receipts: + resource: dft_bus_value_anchors.json concept: dft.local_bus_passenger_fare_receipts - fiscal_start: '2024-04-01' geography_id: E12000007 - allocation: income_quintile_trips - allocation_resource: dft_bus_value_anchors.json - allocation_concept: dft.bus_in_london_trips_per_person - allocation_period_value: 2024 + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + dimension_values: + journey_category: total_concessionary + trips_concept: dft.bus_in_london_trips_per_person + trips_basis: published_series_rate + population_geography_ids: + - E12000001 + - E12000002 + - E12000003 + - E12000004 + - E12000005 + - E12000006 + - E12000007 + - E12000008 + - E12000009 - label: england_outside_london + series: other_local_bus regions: - NORTH_EAST - NORTH_WEST @@ -1424,38 +1649,90 @@ stages: - EAST_MIDLANDS - WEST_MIDLANDS - EAST_OF_ENGLAND + - LONDON - SOUTH_EAST - SOUTH_WEST - resource: dft_bus_value_anchors.json - selector: + receipts: + resource: dft_bus_value_anchors.json concept: dft.local_bus_passenger_fare_receipts - fiscal_start: '2024-04-01' geography_id: dft:england_outside_london - allocation: income_quintile_trips - allocation_resource: dft_bus_value_anchors.json - allocation_concept: dft.other_local_bus_trips_per_person - allocation_period_value: 2024 + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + dimension_values: + journey_category: total_concessionary + trips_concept: dft.other_local_bus_trips_per_person + trips_basis: published_series_rate + population_geography_ids: + - E12000001 + - E12000002 + - E12000003 + - E12000004 + - E12000005 + - E12000006 + - E12000007 + - E12000008 + - E12000009 - label: scotland + series: other_local_bus regions: - SCOTLAND - resource: devolved_bus_finance.json - selector: + receipts: + resource: devolved_bus_finance.json concept: scotgov.bus.operator_revenue - fiscal_start: '2024-04-01' groupby_value_id: passenger_revenue - allocation: uniform + dimension_values: + revenue_component: passenger_revenue + boardings: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: all_passenger_journeys + concessionary: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: concessionary_passenger_journeys + dimension_values: + journey_category: concessionary + trips_concept: dft.other_local_bus_trips_per_person + trips_basis: england_other_local_bus_rate_as_proxy + population_geography_ids: + - S92000003 - label: northern_ireland + series: other_local_bus regions: - NORTHERN_IRELAND - resource: devolved_bus_finance.json - selector: + receipts: + resource: devolved_bus_finance.json concept: dfi_ni.translink_bus.passenger_receipts - fiscal_start: '2024-04-01' sum_over: service: + - metro_glider - ulsterbus + boardings: + resource: devolved_bus_finance.json + concept: dfi_ni.translink_bus.passenger_journeys + sum_over: + service: - metro_glider - allocation: uniform + - ulsterbus + concessionary: + resource: devolved_bus_finance.json + concept: dfi_ni.translink_bus.full_fare_concession_passenger_journeys + dimension_values: + transport_mode: bus + travel_status: full_fare_concession + trips_concept: dft.other_local_bus_trips_per_person + trips_basis: england_other_local_bus_rate_as_proxy + population_geography_ids: + - N92000002 + unpriced_regions: + - WALES + scope_translation: operator receipts carry interchange boardings, non-resident and business payers, and London contactless is not separated, so the yield is per resident trip, not a fare; Wales publishes journeys but no receipts and keeps the chain's raw draw clipped to donor support - kind: fold_into output: domestic_energy_consumption inputs: @@ -1512,7 +1789,7 @@ stages: - electricity_consumption - gas_consumption - has_fuel_consumption - notes: Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (María's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level. + notes: Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the pricing step (María's rulings 2026-09-15 and 2026-09-17), which bounds the region no area prices (Wales keeps the chain's raw draw) while the priced regions move beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Bus fares are priced from journeys (microcosm#930), where the nts_bus_travel stage imputes each person's annual bus-in-London and other-local-bus trips and their concessionary eligibility, and the declared price_bus_journeys step sets bus_fare_spending as the sum over the household's non-eligible persons of trips times boardings per resident trip (the published BUS01 journeys over the published NTS0705a trips per resident times the ONS population) times the yield per fare-paying boarding (BUS05ai receipts over journeys less concessionary journeys), per area; bus-in-London trips take the London area's price for every resident, other-local-bus trips the price of the residence area (England outside London; Scotland and Northern Ireland from their own receipts and journeys with England's trip rate as the declared proxy); Wales is unpriced and keeps the raw draw. The chain still draws bus_fare_spending so later targets condition on the same raw draw; the emitted column is the priced value. The receipt records every factor, the frame-implied boardings beside the published ones and the frame's eligible trip share beside the publisher's concessionary boarding share, so the design-weight fit of the bound receipts targets is read as a composition check, never a level the stage set; the #890 incidence draw and fare rake are retired. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level. - stage: etb_vat survey: Effects of Taxes and Benefits 1977-2024 source: UK Data Service SN 8856 Effects of Taxes and Benefits household tab and cited VAT anchor resource. @@ -1610,6 +1887,10 @@ stages: resource: devolved_bus_finance.json kind: public_aggregate_reference format: json + - role: dft_bus_journeys + resource: dft_bus_journeys.json + kind: public_aggregate_reference + format: json operations: - kind: derive year: max @@ -1742,6 +2023,139 @@ stages: joint_columns: - bus_subsidy_spending - rail_subsidy_spending + - kind: record_support_per_journey + support_column: bus_subsidy_spending + trips_columns: + bus_in_london: bus_in_london_trips + other_local_bus: other_local_bus_trips + eligibility_column: bus_pass_eligible + fiscal_start: '2024-04-01' + trip_rates_resource: dft_bus_value_anchors.json + trip_rates_period_value: 2024 + population_resource: dft_bus_journeys.json + population_period_value: 2024 + pricing_areas: + - label: london + series: bus_in_london + receipts: + resource: dft_bus_value_anchors.json + concept: dft.local_bus_passenger_fare_receipts + geography_id: E12000007 + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + dimension_values: + journey_category: total_concessionary + trips_concept: dft.bus_in_london_trips_per_person + trips_basis: published_series_rate + population_geography_ids: + - E12000001 + - E12000002 + - E12000003 + - E12000004 + - E12000005 + - E12000006 + - E12000007 + - E12000008 + - E12000009 + - label: england_outside_london + series: other_local_bus + regions: + - NORTH_EAST + - NORTH_WEST + - YORKSHIRE + - EAST_MIDLANDS + - WEST_MIDLANDS + - EAST_OF_ENGLAND + - SOUTH_EAST + - SOUTH_WEST + - LONDON + receipts: + resource: dft_bus_value_anchors.json + concept: dft.local_bus_passenger_fare_receipts + geography_id: dft:england_outside_london + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + dimension_values: + journey_category: total_concessionary + trips_concept: dft.other_local_bus_trips_per_person + trips_basis: published_series_rate + population_geography_ids: + - E12000001 + - E12000002 + - E12000003 + - E12000004 + - E12000005 + - E12000006 + - E12000007 + - E12000008 + - E12000009 + unpriced_regions: + - SCOTLAND + - WALES + - NORTHERN_IRELAND + support_areas: + - label: london + regions: + - LONDON + reimbursement: + resource: dft_bus_journeys.json + concept: dft.local_bus_concessionary_travel_reimbursement + geography_id: E12000007 + net_support: + resource: dft_bus_value_anchors.json + concept: dft.local_bus_total_estimated_net_support + geography_id: E12000007 + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: E12000007 + dimension_values: + journey_category: total_concessionary + - label: england_outside_london + regions: + - NORTH_EAST + - NORTH_WEST + - YORKSHIRE + - EAST_MIDLANDS + - WEST_MIDLANDS + - EAST_OF_ENGLAND + - SOUTH_EAST + - SOUTH_WEST + reimbursement: + resource: dft_bus_journeys.json + concept: dft.local_bus_concessionary_travel_reimbursement + geography_id: dft:england_outside_london + net_support: + resource: dft_bus_value_anchors.json + concept: dft.local_bus_total_estimated_net_support + geography_id: dft:england_outside_london + boardings: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + concessionary: + resource: dft_bus_journeys.json + concept: dft.local_bus_passenger_journeys + geography_id: dft:england_outside_london + dimension_values: + journey_category: total_concessionary + basis: value-side alternative recorded beside the raked column, never applied (microcosm#930, María's ruling pending); England only, where DfT publishes the reimbursement and net support by area - kind: compute_ratio output: rail_usage numerator: rail_subsidy_spending 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 9b006cbd8..28a096c3b 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 @@ -1625,6 +1625,14 @@ def _ledger_compile_parity_required_artifacts( "margins", "margins_period_value", "maximum_connected_share_deviation", + # #930 bus_travel_facts check: NTS0313 incidence and NTS0303 + # trip rates recomputed from the vendored rows. + "trip_rates_period_value", + "maximum_user_share_deviation", + "maximum_trip_rate_deviation", + # #930 fact_rake check on a declared rake receipt. + "receipt_key", + "allowed_resources", } ), artifact_keys=frozenset({"stage_evidence"}), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_fare_pricing.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_fare_pricing.py new file mode 100644 index 000000000..f4d4f731b --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_fare_pricing.py @@ -0,0 +1,466 @@ +"""Bus fares priced from imputed journeys at a published yield (microcosm#930). + +The lcfs stage used to set ``bus_fare_spending`` by raking the diary draw to +the DfT receipts it is calibrated against (microcosm#890, rake-then-bind). +Here the level comes from a quantity the ``nts_bus_travel`` stage imputed and +two published ratios, so the calibration targets constrain something the +stage did not set: + +* the yield per fare-paying boarding, ``y = R / (B - C)``: BUS05ai passenger + fare receipts over BUS01 passenger journeys less the concessionary journeys, + per area (London and England outside London; Scotland and Northern Ireland + from their own receipts and journeys); +* boardings per resident trip, ``k = B / (T x P)``: the published boardings over + the published NTS trips per resident times the resident population, per + series, which translates a survey trip (one-way, main mode, England + residents) into operator boardings (interchanges, non-residents, business + payers; London contactless is not separated). + +A person's fares are ``sum over series of trips x k x y`` unless the person is +concessionary-eligible under the statutory rule of their area, whose trips are +priced at zero. ``bus_in_london`` trips of every resident take the London area's +price; ``other_local_bus`` trips take the price of the person's residence area. +Regions with no published receipts (Wales) are left unpriced and keep the +chain's raw draw, clipped to donor support (María's ruling, 2026-09-17). + +Every input is a vendored Chronicle row; the receipt records every factor, the +frame-implied boardings beside the published ones, and the frame's eligible +trip share beside the publisher's concessionary boarding share, so the +design-weight fit of the bound receipts targets can be read as what it is: a +survey-versus-survey composition check times a survey-versus-admin concession +check, never a level the stage set. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from dataclasses import dataclass +from typing import Any + +import numpy as np +import pandas as pd + +from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows + +PRICE_BUS_JOURNEYS_KIND = "price_bus_journeys" +UK_DFT_BUS_JOURNEYS_RESOURCE = "dft_bus_journeys.json" +BUS_IN_LONDON = "bus_in_london" +OTHER_LOCAL_BUS = "other_local_bus" +SERIES: tuple[str, str] = (BUS_IN_LONDON, OTHER_LOCAL_BUS) +ONS_POPULATION_CONCEPT = "ons.mid_year_population_estimate" + + +class BusFarePricingError(ValueError): + """Raised when the declaration, the vendored rows or the frame refuse pricing.""" + + +def _mapping(value: object, label: str) -> Mapping[str, Any]: + if not isinstance(value, Mapping): + raise BusFarePricingError(f"{label} must be a mapping.") + return value + + +def published_fact( + selector: Mapping[str, Any], + *, + unit: str, + allowed_resources: Sequence[str], + fiscal_start: str | None = None, + period_value: int | None = None, +) -> tuple[float, dict[str, Any]]: + """One positive published value from vendored rows under a declared selector. + + ``selector`` names ``resource`` and ``concept`` and may pin + ``geography_id``, ``groupby_value_id``, ``dimension_values`` (all must + match) or ``sum_over`` (one dimension, every named value summed). Rows + with dimensions are excluded unless the selector asks for them, so a + concept that carries both a total and a split resolves to its total. + """ + + resource = str(selector.get("resource") or "") + if resource not in allowed_resources: + raise BusFarePricingError( + f"selector names {resource!r}, not a resource the stage declares " + f"({sorted(allowed_resources)})." + ) + criteria: dict[str, Any] = {"concept": str(selector["concept"])} + for key in ("geography_id", "groupby_value_id"): + if selector.get(key): + criteria[key] = str(selector[key]) + if period_value is not None: + criteria["period_value"] = int(period_value) + dimension_values = { + str(k): str(v) for k, v in dict(selector.get("dimension_values") or {}).items() + } + if dimension_values: + criteria["dimensions"] = dimension_values + rows = vendored_rows(resource, fiscal_start=fiscal_start, **criteria) + sum_over = dict(selector.get("sum_over") or {}) + if sum_over: + if len(sum_over) != 1: + raise BusFarePricingError("sum_over names exactly one dimension.") + ((dimension, values),) = sum_over.items() + wanted = sorted(str(v) for v in values) + rows = [ + row + for row in rows + if str((row.get("dimensions") or {}).get(dimension)) in wanted + ] + found = sorted( + str((row.get("dimensions") or {}).get(dimension)) for row in rows + ) + if found != wanted: + raise BusFarePricingError( + f"{resource}: sum_over {dimension!r} expected {wanted}, found {found}." + ) + else: + if not dimension_values: + rows = [row for row in rows if not (row.get("dimensions") or {})] + if len(rows) != 1: + raise BusFarePricingError( + f"{resource}: expected exactly one row for {dict(selector)}, " + f"found {len(rows)}." + ) + units = {str(row.get("unit")) for row in rows} + if units != {unit}: + raise BusFarePricingError( + f"{resource}: expected {unit!r} rows for {dict(selector)}, got {sorted(units)}." + ) + value = float(sum(float(row["value"]) for row in rows)) + if not np.isfinite(value) or value <= 0: + raise BusFarePricingError( + f"{resource}: published value for {dict(selector)} must be positive." + ) + return value, { + "selector": dict(selector), + "value": value, + "unit": unit, + "source_record_ids": [str(row.get("source_record_id", "")) for row in rows], + } + + +@dataclass(frozen=True) +class AreaPrice: + """The published inputs and derived factors of one priced area.""" + + label: str + series: str + regions: tuple[str, ...] + receipts: float + boardings: float + concessionary_boardings: float + trips_per_person: float + population: float + boardings_per_trip: float + yield_per_fare_paying_boarding: float + fare_per_trip: float + concessionary_boarding_share: float + trips_basis: str + receipt: dict[str, Any] + + +@dataclass(frozen=True) +class BusFarePrices: + london: AreaPrice + other_by_region: Mapping[str, AreaPrice] + unpriced_regions: frozenset[str] + receipt: dict[str, Any] + + def area_for_region(self, region: str) -> AreaPrice | None: + return self.other_by_region.get(str(region)) + + +def bus_fare_prices( + parameters: Mapping[str, Any], *, allowed_resources: Sequence[str] +) -> BusFarePrices: + """Resolve every area's price from the declaration and the vendored rows.""" + + if parameters.get("kind", PRICE_BUS_JOURNEYS_KIND) != PRICE_BUS_JOURNEYS_KIND: + raise BusFarePricingError("not a price_bus_journeys declaration.") + fiscal_start = str(parameters["fiscal_start"]) + trip_rates_resource = str(parameters["trip_rates_resource"]) + trip_rates_period = int(parameters["trip_rates_period_value"]) + population_resource = str(parameters["population_resource"]) + population_period = int(parameters["population_period_value"]) + areas = parameters.get("areas") + if not isinstance(areas, list) or not areas: + raise BusFarePricingError("price_bus_journeys declares no areas.") + unpriced = frozenset(str(r) for r in parameters.get("unpriced_regions", ())) + london: AreaPrice | None = None + other_by_region: dict[str, AreaPrice] = {} + area_receipts: list[dict[str, Any]] = [] + for area in areas: + area = _mapping(area, "areas[]") + label = str(area["label"]) + series = str(area["series"]) + if series not in SERIES: + raise BusFarePricingError( + f"area {label!r} names an unknown series {series!r}." + ) + regions = tuple(str(r) for r in area.get("regions", ())) + receipts, receipts_receipt = published_fact( + _mapping(area["receipts"], f"{label}.receipts"), + unit="gbp", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + boardings, boardings_receipt = published_fact( + _mapping(area["boardings"], f"{label}.boardings"), + unit="count", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + concessionary, concessionary_receipt = published_fact( + _mapping(area["concessionary"], f"{label}.concessionary"), + unit="count", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + if concessionary >= boardings: + raise BusFarePricingError( + f"area {label!r}: concessionary journeys {concessionary} are not " + f"below total journeys {boardings}." + ) + trips_concept = str(area["trips_concept"]) + trips_per_person, trips_receipt = published_fact( + { + "resource": trip_rates_resource, + "concept": trips_concept, + "groupby_value_id": "all", + }, + unit="trips_per_person_per_year", + allowed_resources=allowed_resources, + period_value=trip_rates_period, + ) + population_ids = [str(g) for g in area.get("population_geography_ids", ())] + if not population_ids: + raise BusFarePricingError(f"area {label!r} names no population geography.") + population = 0.0 + population_records: list[str] = [] + for geography_id in population_ids: + value, receipt = published_fact( + { + "resource": population_resource, + "concept": ONS_POPULATION_CONCEPT, + "geography_id": geography_id, + }, + unit="count", + allowed_resources=allowed_resources, + period_value=population_period, + ) + population += value + population_records.extend(receipt["source_record_ids"]) + resident_trips = trips_per_person * population + k = boardings / resident_trips + y = receipts / (boardings - concessionary) + price = AreaPrice( + label=label, + series=series, + regions=regions, + receipts=receipts, + boardings=boardings, + concessionary_boardings=concessionary, + trips_per_person=trips_per_person, + population=population, + boardings_per_trip=k, + yield_per_fare_paying_boarding=y, + fare_per_trip=k * y, + concessionary_boarding_share=concessionary / boardings, + trips_basis=str(area.get("trips_basis", "published_series_rate")), + receipt={ + "label": label, + "series": series, + "regions": list(regions), + "receipts": receipts_receipt, + "boardings": boardings_receipt, + "concessionary": concessionary_receipt, + "trips_per_person": trips_receipt, + "population": { + "geography_ids": population_ids, + "period_value": population_period, + "value": population, + "source_record_ids": population_records, + }, + "published_resident_trips": resident_trips, + "boardings_per_trip": k, + "yield_per_fare_paying_boarding": y, + "fare_per_trip": k * y, + "concessionary_boarding_share": concessionary / boardings, + "trips_basis": str(area.get("trips_basis", "published_series_rate")), + }, + ) + area_receipts.append(price.receipt) + if series == BUS_IN_LONDON: + if london is not None or regions: + raise BusFarePricingError( + "exactly one area prices the bus_in_london series, for every " + "resident, and declares no regions." + ) + london = price + else: + if not regions: + raise BusFarePricingError(f"area {label!r} declares no regions.") + for region in regions: + if region in other_by_region or region in unpriced: + raise BusFarePricingError(f"region {region!r} is priced twice.") + other_by_region[region] = price + if london is None: + raise BusFarePricingError("no area prices the bus_in_london series.") + receipt = { + "fiscal_start": fiscal_start, + "trip_rates_period_value": trip_rates_period, + "population_period_value": population_period, + "areas": area_receipts, + "unpriced_regions": sorted(unpriced), + "scope_translation": str(parameters.get("scope_translation", "")), + "algebra": ( + "fare = sum over series of trips x k x y with k = B / (T x P) and " + "y = R / (B - C); frame / R = [frame trips / (T x P)] x " + "[frame fare-paying trip share / (1 - C / B)]: a survey-versus-survey " + "composition check times a survey-versus-admin concession check, " + "never a level the stage set." + ), + } + return BusFarePrices( + london=london, + other_by_region=other_by_region, + unpriced_regions=unpriced, + receipt=receipt, + ) + + +def price_bus_journeys( + person: pd.DataFrame, + household: pd.DataFrame, + *, + prices: BusFarePrices, + trips_columns: Mapping[str, str], + eligibility_column: str, + household_weights: np.ndarray, + raw_household_fares: np.ndarray, +) -> tuple[np.ndarray, np.ndarray, dict[str, Any]]: + """Household fares from persons' journeys; unpriced regions keep the raw draw. + + Returns the household fare vector, the boolean mask of priced households + and the receipt (factors, persons priced and zeroed, the frame-implied + boardings and eligible trip share per area, totals before and after). + """ + + for series in SERIES: + if series not in trips_columns: + raise BusFarePricingError(f"trips_columns lacks the {series} series.") + needed = ("person_household_id", eligibility_column, *trips_columns.values()) + missing = [c for c in needed if c not in person] + if missing: + raise BusFarePricingError( + f"the person table lacks {missing}; the nts_bus_travel stage must run first." + ) + for column in ("household_id", "region"): + if column not in household: + raise BusFarePricingError(f"the household table lacks {column!r}.") + weights = np.asarray(household_weights, dtype=float) + if len(weights) != len(household): + raise BusFarePricingError( + "household_weights must align with the household table." + ) + region_by_household = household.set_index("household_id")["region"].map( + lambda v: str(getattr(v, "name", v)) + ) + hh_ids = person["person_household_id"].to_numpy() + person_region = region_by_household.reindex(hh_ids).to_numpy().astype(str) + weight_by_household = pd.Series(weights, index=household["household_id"].to_numpy()) + person_weight = ( + weight_by_household.reindex(hh_ids).fillna(0.0).to_numpy(dtype=float) + ) + eligible = person[eligibility_column].to_numpy(dtype=bool) + london_trips = person[trips_columns[BUS_IN_LONDON]].to_numpy(dtype=float) + other_trips = person[trips_columns[OTHER_LOCAL_BUS]].to_numpy(dtype=float) + known = set(prices.other_by_region) | set(prices.unpriced_regions) + unknown = sorted(set(person_region) - known) + if unknown: + raise BusFarePricingError( + f"regions {unknown} are neither priced nor declared unpriced." + ) + unpriced_person = np.isin(person_region, sorted(prices.unpriced_regions)) + fare = np.zeros(len(person), dtype=float) + per_area: dict[str, dict[str, float]] = {} + + def _accumulate( + label: str, trips: np.ndarray, mask: np.ndarray, area: AreaPrice + ) -> None: + entry = per_area.setdefault( + label, + { + "weighted_trips": 0.0, + "weighted_eligible_trips": 0.0, + "weighted_fare_paying_trips": 0.0, + "frame_implied_boardings": 0.0, + "published_boardings": area.boardings, + "fares": 0.0, + "persons": 0.0, + }, + ) + w = person_weight[mask] + t = trips[mask] + e = eligible[mask] + entry["weighted_trips"] += float(np.dot(t, w)) + entry["weighted_eligible_trips"] += float(np.dot(t[e], w[e])) + entry["weighted_fare_paying_trips"] += float(np.dot(t[~e], w[~e])) + entry["frame_implied_boardings"] += ( + float(np.dot(t, w)) * area.boardings_per_trip + ) + entry["persons"] += float(mask.sum()) + priced = np.where(e, 0.0, t * area.fare_per_trip) + entry["fares"] += float(np.dot(priced, w)) + fare[mask] += priced + + _accumulate("london_series", london_trips, ~unpriced_person, prices.london) + for region, area in prices.other_by_region.items(): + mask = person_region == region + if mask.any(): + _accumulate(area.label, other_trips, mask, area) + household_fare = ( + pd.Series(fare, index=hh_ids) + .groupby(level=0) + .sum() + .reindex(household["household_id"].to_numpy()) + .fillna(0.0) + .to_numpy(dtype=float) + ) + household_region = ( + household["region"].map(lambda v: str(getattr(v, "name", v))).to_numpy() + ) + priced_household = ~np.isin(household_region, sorted(prices.unpriced_regions)) + raw = np.asarray(raw_household_fares, dtype=float) + result = np.where(priced_household, household_fare, raw) + for entry in per_area.values(): + entry["frame_implied_over_published_boardings"] = ( + entry["frame_implied_boardings"] / entry["published_boardings"] + if entry["published_boardings"] > 0 + else None + ) + entry["frame_eligible_trip_share"] = ( + entry["weighted_eligible_trips"] / entry["weighted_trips"] + if entry["weighted_trips"] > 0 + else None + ) + receipt = { + "persons": int(len(person)), + "persons_priced": int((~unpriced_person).sum()), + "persons_eligible_zero_priced": int((eligible & ~unpriced_person).sum()), + "households_priced": int(priced_household.sum()), + "households_unpriced_keep_raw_draw": int((~priced_household).sum()), + "unpriced_regions": sorted(prices.unpriced_regions), + "by_area": per_area, + "weighted_fares_before": float( + np.dot(raw[priced_household], weights[priced_household]) + ), + "weighted_fares_after": float( + np.dot(result[priced_household], weights[priced_household]) + ), + "prices": { + "london_series": prices.london.receipt, + **{a.label: a.receipt for a in prices.other_by_region.values()}, + }, + } + return result, priced_household, receipt diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py new file mode 100644 index 000000000..27ebc11b1 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py @@ -0,0 +1,195 @@ +"""What a value-side treatment of bus support would give, recorded not applied. + +The ETB stage rakes ``bus_subsidy_spending`` to the published net support per +area and calibration binds the same facts (the rake-then-bind shape microcosm#930 +retires for fares). This diagnostic records, per residence area, what the +support would be if it were priced from the frame's journeys the way fares now +are: the published concessionary travel reimbursement per concessionary +boarding times the frame's eligible boardings, plus the rest of the net +support per boarding times every boarding, beside the raked column's +design-weighted total. Boardings are the ``nts_bus_travel`` trips times the +boardings-per-resident-trip translation of the fare pricing (the same +published BUS01 over NTS0705a times population), so the two columns share +one quantity. Every input is a vendored Chronicle row (the BUS01 journeys, +concessionary journeys and BUS05 reimbursement in ``dft_bus_journeys.json``, +the net support in ``dft_bus_value_anchors.json``); nothing here changes a +value — the switch is María's ruling with these numbers in hand. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from typing import Any + +import numpy as np +import pandas as pd + +from microcosm.build.uk_runtime.bus_fare_pricing import ( + BUS_IN_LONDON, + OTHER_LOCAL_BUS, + BusFarePricingError, + bus_fare_prices, + published_fact, +) + +RECORD_SUPPORT_PER_JOURNEY_KIND = "record_support_per_journey" + + +def support_per_journey_diagnostic( + parameters: Mapping[str, Any], + *, + person: pd.DataFrame, + household: pd.DataFrame, + household_weights: np.ndarray, + raked_support: np.ndarray, + allowed_resources: Sequence[str], +) -> dict[str, Any]: + """The receipt of the value-side alternative, per declared residence area.""" + + if parameters.get("kind", RECORD_SUPPORT_PER_JOURNEY_KIND) != ( + RECORD_SUPPORT_PER_JOURNEY_KIND + ): + raise BusFarePricingError("not a record_support_per_journey declaration.") + pricing = { + "kind": "price_bus_journeys", + "column": "bus_fare_spending", + "trips_columns": dict(parameters["trips_columns"]), + "eligibility_column": str(parameters["eligibility_column"]), + "fiscal_start": str(parameters["fiscal_start"]), + "trip_rates_resource": str(parameters["trip_rates_resource"]), + "trip_rates_period_value": int(parameters["trip_rates_period_value"]), + "population_resource": str(parameters["population_resource"]), + "population_period_value": int(parameters["population_period_value"]), + "areas": list(parameters["pricing_areas"]), + "unpriced_regions": list(parameters.get("unpriced_regions", ())), + } + prices = bus_fare_prices(pricing, allowed_resources=allowed_resources) + trips_columns = { + str(k): str(v) for k, v in dict(parameters["trips_columns"]).items() + } + eligibility = str(parameters["eligibility_column"]) + support_column = str(parameters["support_column"]) + for column in ("person_household_id", eligibility, *trips_columns.values()): + if column not in person: + raise BusFarePricingError( + f"the person table lacks {column!r}; the nts_bus_travel stage must run first." + ) + weights = np.asarray(household_weights, dtype=float) + region_by_household = household.set_index("household_id")["region"].map( + lambda v: str(getattr(v, "name", v)) + ) + hh_ids = person["person_household_id"].to_numpy() + person_region = region_by_household.reindex(hh_ids).to_numpy().astype(str) + person_weight = ( + pd.Series(weights, index=household["household_id"].to_numpy()) + .reindex(hh_ids) + .fillna(0.0) + .to_numpy(dtype=float) + ) + eligible = person[eligibility].to_numpy(dtype=bool) + london_trips = person[trips_columns[BUS_IN_LONDON]].to_numpy(dtype=float) + other_trips = person[trips_columns[OTHER_LOCAL_BUS]].to_numpy(dtype=float) + k_london = prices.london.boardings_per_trip + household_region = ( + household["region"].map(lambda v: str(getattr(v, "name", v))).to_numpy() + ) + raked = np.asarray(raked_support, dtype=float) + by_area: dict[str, dict[str, Any]] = {} + for area in parameters["support_areas"]: + area = dict(area) + label = str(area["label"]) + regions = tuple(str(r) for r in area["regions"]) + fiscal_start = str(parameters["fiscal_start"]) + reimbursement, reimbursement_receipt = published_fact( + dict(area["reimbursement"]), + unit="gbp", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + net_support, net_support_receipt = published_fact( + dict(area["net_support"]), + unit="gbp", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + boardings, boardings_receipt = published_fact( + dict(area["boardings"]), + unit="count", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + concessionary, concessionary_receipt = published_fact( + dict(area["concessionary"]), + unit="count", + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + if net_support < reimbursement: + raise BusFarePricingError( + f"area {label!r}: net support {net_support} is below the concessionary " + f"reimbursement {reimbursement} it contains." + ) + reimbursement_per_concessionary_boarding = reimbursement / concessionary + other_support_per_boarding = (net_support - reimbursement) / boardings + mask = np.isin(person_region, regions) + # Boardings of the area's residents: each series at its own translation. + k_other = np.zeros(len(person), dtype=float) + for region in regions: + price = prices.area_for_region(region) + if price is None: + raise BusFarePricingError( + f"area {label!r} names {region!r}, which the pricing areas do not price." + ) + k_other[person_region == region] = price.boardings_per_trip + person_boardings = london_trips * k_london + other_trips * k_other + all_boardings = float(np.dot(person_boardings[mask], person_weight[mask])) + eligible_boardings = float( + np.dot(person_boardings[mask & eligible], person_weight[mask & eligible]) + ) + value_side = ( + reimbursement_per_concessionary_boarding * eligible_boardings + + other_support_per_boarding * all_boardings + ) + household_mask = np.isin(household_region, regions) + raked_total = float(np.dot(raked[household_mask], weights[household_mask])) + by_area[label] = { + "regions": list(regions), + "reimbursement": reimbursement_receipt, + "net_support": net_support_receipt, + "boardings": boardings_receipt, + "concessionary": concessionary_receipt, + "reimbursement_per_concessionary_boarding": reimbursement_per_concessionary_boarding, + "other_support_per_boarding": other_support_per_boarding, + "frame_boardings": all_boardings, + "frame_eligible_boardings": eligible_boardings, + "frame_eligible_boarding_share": ( + eligible_boardings / all_boardings if all_boardings > 0 else None + ), + "published_concessionary_boarding_share": concessionary / boardings, + "value_side_support": value_side, + "raked_support": raked_total, + "value_side_over_raked": ( + value_side / raked_total if raked_total > 0 else None + ), + "households": int(household_mask.sum()), + "persons": int(mask.sum()), + } + return { + "operation": RECORD_SUPPORT_PER_JOURNEY_KIND, + "support_column": support_column, + "applied": False, + "basis": ( + "reimbursement per concessionary boarding times the frame's eligible " + "boardings plus the rest of the net support per boarding times every " + "boarding; boardings are nts_bus_travel trips times the fare pricing's " + "boardings per resident trip" + ), + "boardings_per_trip": { + "bus_in_london": k_london, + **{ + a.label: a.boardings_per_trip + for a in {a.label: a for a in prices.other_by_region.values()}.values() + }, + }, + "by_area": by_area, + } diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_use_incidence.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_use_incidence.py index 0d07d5ce0..aaebc2d6d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_use_incidence.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_use_incidence.py @@ -101,10 +101,14 @@ def nts_band_shares(parameters: Mapping[str, Any]) -> tuple[BusUseBandShares, di share_geography = str(parameters["share_geography"]) share_age_coverage = str(parameters["share_age_coverage"]) applied_to = str(parameters["applied_to"]) - if share_age_coverage != "all_ages" or applied_to != "fare_rake_regions": + if share_age_coverage != "all_ages" or applied_to not in ( + "fare_rake_regions", + "every_person", + ): raise ValueError( "assign_bus_use_incidence supports share_age_coverage all_ages applied " - "to fare_rake_regions only." + "to fare_rake_regions (the lcfs override) or every_person (the " + "nts_bus_travel fallback) only." ) mode_groupby = str(parameters.get("transport_mode_groupby_value_id") or "local_bus") older_age_band = str(parameters.get("older_age_band") or "60 and over") 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 a39185193..2386c475e 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 @@ -131,11 +131,15 @@ class UKCalibrationRunResult: UK_SPINE_GATE_SCOPE = ( "uk_stage_was_wealth_support", + "uk_stage_nts_bus_travel_support", + "uk_stage_nts_bus_travel_facts", "uk_stage_uc_deduction_attributes", "uk_stage_lcfs_consumption_support", "uk_stage_lcfs_consumption_energy_rake", + "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", + "uk_stage_etb_services_support_rake", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", 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 6c03b50f7..7cf092d13 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 @@ -12,6 +12,10 @@ from microcosm.build.gates import FitWeightRecord from microcosm.build.source_manifest import SourceStageSpec +from microcosm.build.uk_runtime.bus_support_per_journey import ( + RECORD_SUPPORT_PER_JOURNEY_KIND, + support_per_journey_diagnostic, +) from microcosm.build.uk_runtime.donor_uprating import ( apply_donor_uprating, donor_uprating_factors, @@ -102,6 +106,7 @@ "orr_rail_facts.json", "dft_bus_value_anchors.json", "devolved_bus_finance.json", + "dft_bus_journeys.json", ) @@ -114,6 +119,7 @@ class UKETBServicesResult: nhs_cells: dict[str, object] = field(default_factory=dict) donor_uprating: dict[str, object] | None = None bus_support_rake: dict[str, object] | None = None + support_per_journey: dict[str, object] | None = None def evidence(self) -> dict[str, object]: evidence: dict[str, object] = { @@ -125,6 +131,8 @@ def evidence(self) -> dict[str, object]: evidence["donor_uprating"] = dict(self.donor_uprating) if self.bus_support_rake is not None: evidence["bus_support_rake"] = dict(self.bus_support_rake) + if self.support_per_journey is not None: + evidence["support_per_journey"] = dict(self.support_per_journey) return evidence @@ -186,6 +194,13 @@ def __call__(self, frame: Frame) -> Frame: household=household, weights=frame.weights_for("household").values, ) + support_receipt = etb_support_per_journey( + self.stage, + draws, + frame=frame, + household=household, + weights=frame.weights_for("household").values, + ) draws["rail_usage"] = draws["rail_subsidy_spending"] / config["rail_fare_index"] for column in UK_ETB_SERVICES_HOUSEHOLD_OUTPUT_COLUMNS: household[column] = draws[column].to_numpy() @@ -222,6 +237,7 @@ def __call__(self, frame: Frame) -> Frame: nhs_cells=nhs_cells, donor_uprating=uprating_receipt, bus_support_rake=rake_receipt, + support_per_journey=support_receipt, ) return result @@ -504,6 +520,41 @@ def etb_bus_support_rake( return raked, receipts[0] if len(receipts) == 1 else {"operations": receipts} +def etb_support_per_journey( + stage: SourceStageSpec, + draws: pd.DataFrame, + *, + frame: Frame, + household: pd.DataFrame, + weights: np.ndarray, +) -> dict[str, object] | None: + """Record what pricing support from journeys would give (microcosm#930).""" + + parameters = next( + ( + dict(operation.parameters) + for operation in stage.operations + if operation.kind == RECORD_SUPPORT_PER_JOURNEY_KIND + ), + None, + ) + if parameters is None: + return None + column = str(parameters["support_column"]) + if column not in draws: + raise KeyError( + f"record_support_per_journey names {column!r}, not a drawn column." + ) + return support_per_journey_diagnostic( + parameters, + person=frame.table("person"), + household=household, + household_weights=np.asarray(weights, dtype=float), + raked_support=draws[column].to_numpy(dtype=float), + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + + #: The declared rake levels bus support; the support clip and the committed #: support bounds leave it alone. UK_ETB_SERVICES_RAKED_COLUMNS = frozenset({"bus_subsidy_spending"}) 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 93e71afd1..410db23f4 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -114,6 +114,7 @@ "frs_education": ("frs",), "frs_legacy_proxies": ("frs",), "was_wealth": ("was",), + "nts_bus_travel": ("nts_household", "nts_individual", "nts_trip"), "lcfs_consumption": ("lcfs_household", "lcfs_person"), "etb_vat": ("etb",), "etb_services": ("etb",), @@ -124,6 +125,9 @@ _SPLIT_SOURCE_DESCRIPTIONS = { "frs": "Pinned local FRS table directory.", "was": "Pinned local WAS household donor table.", + "nts_household": "Pinned local NTS household donor table.", + "nts_individual": "Pinned local NTS individual donor table.", + "nts_trip": "Pinned local NTS trip donor table.", "lcfs_household": "Pinned local LCFS household donor table.", "lcfs_person": "Pinned local LCFS person donor table.", "etb": "Pinned local ETB household donor table.", @@ -197,6 +201,9 @@ ("household", "property_wealth"), } ), + # The NTS band model materializes an engine predictor (household gross + # income) over the whole frame, an open surface like the LCFS QRF. + "nts_bus_travel": None, "lcfs_consumption": None, "etb_vat": None, "etb_services": None, @@ -525,6 +532,15 @@ def _cells( *_cells("household", ("mortgage_debt", "consumer_debt")), _Cell("person", "student_loan_balance", "float64"), ), + "nts_bus_travel": ( + _Cell("person", "local_bus_use_band", "int64"), + *_cells( + "person", + ("bus_in_london_trips", "other_local_bus_trips", "local_bus_trips"), + ), + _Cell("person", "bus_pass_eligible", "bool"), + _Cell("household", "household_local_bus_trips", "float64"), + ), "regional_property_uprating": _cells( "household", ("main_residence_value", "property_wealth") ), 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 04bb336ac..06d6f8437 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 @@ -44,7 +44,7 @@ ) from microcosm.graph.population import dtype_for_token -from . import uc_relationships +from . import bus_use_incidence, uc_relationships from .national_frame import UK_NATIONAL_SCHEMA from .rowwise_geography import id_multiplier_for_values @@ -76,6 +76,7 @@ "frs_household_draws": "frs_household_draws", "frs_brma": "frs_brma", "was_wealth": "was_wealth", + "nts_bus_travel": "nts_bus_travel", "regional_property_uprating": "regional_uprating", "lcfs_consumption": "lcfs_consumption", "etb_vat": "etb_vat", @@ -104,6 +105,7 @@ "frs_education_grant_split": (uk_engine_adapter,), "frs_brma": (uk_engine_adapter,), "was_wealth": (uk_engine_adapter,), + "nts_bus_travel": (uk_engine_adapter, bus_use_incidence), "lcfs_consumption": (uk_engine_adapter,), "etb_vat": (uk_engine_adapter,), "etb_services": (uk_engine_adapter,), @@ -336,7 +338,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 30-stage spine " + "UK parity fixture must describe the current 31-stage spine " f"(missing={missing}, extra={extra})." ) return descriptor, stages @@ -369,6 +371,7 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: from .frs_relationships import UKFRSRelationshipsStageTransform from .frs_take_up import UKFRSTakeUpStageTransform from .lcfs_consumption import UKLCFSConsumptionStageTransform + from .nts_bus_travel import UKNTSBusTravelStageTransform from .regional_uprating import UKRegionalPropertyUpratingStageTransform from .salary_sacrifice import UKSalarySacrificeStageTransform from .spi_spine import ( @@ -402,6 +405,15 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: etb = pd.read_csv( _fixture_input(source, inputs, "etb"), float_precision="round_trip" ) + nts_household = pd.read_csv( + _fixture_input(source, inputs, "nts_household"), float_precision="round_trip" + ) + nts_individual = pd.read_csv( + _fixture_input(source, inputs, "nts_individual"), float_precision="round_trip" + ) + nts_trip = pd.read_csv( + _fixture_input(source, inputs, "nts_trip"), float_precision="round_trip" + ) spi_path = _fixture_input(source, inputs, "spi_donor") spi_donor = pd.read_csv(spi_path, float_precision="round_trip") hmrc_targets_path = _fixture_input(source, inputs, "hmrc_income_targets") @@ -462,6 +474,13 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: "was_wealth": UKWASWealthStageTransform( stage=stages["was_wealth"], engine=engine, donor=was ), + "nts_bus_travel": UKNTSBusTravelStageTransform( + stage=stages["nts_bus_travel"], + engine=engine, + nts_household=nts_household, + nts_individual=nts_individual, + nts_trip=nts_trip, + ), "regional_property_uprating": UKRegionalPropertyUpratingStageTransform( stage=stages["regional_property_uprating"] ), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py index f464bed01..ba1d23670 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py @@ -16,11 +16,11 @@ assign_binary_from_rate, stable_identity_uniforms, ) -from microcosm.build.uk_runtime.bus_use_incidence import ( - BusUseIncidenceResult, - assign_bus_use_incidence, - incidence_operation, - nts_band_shares, +from microcosm.build.uk_runtime.bus_fare_pricing import ( + PRICE_BUS_JOURNEYS_KIND, + UK_DFT_BUS_JOURNEYS_RESOURCE, + bus_fare_prices, + price_bus_journeys, ) from microcosm.build.uk_runtime.donor_uprating import ( apply_donor_uprating, @@ -49,11 +49,6 @@ rake_energy_kwh, spend_to_kwh, ) -from microcosm.build.uk_runtime.fact_raking import ( - rake_operations, - rake_to_facts, - resolve_cells, -) from microcosm.build.uk_runtime.frs_spine import read_pinned_tab from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows from microcosm.build.uk_runtime.national_frame import ( @@ -158,21 +153,23 @@ #: these and no other (the vendor register lists this module as their consumer). UK_LCFS_ROAD_FUEL_RESOURCE = "road_fuel_anchors.json" UK_LCFS_LICENSED_CARS_RESOURCE = "licensed_cars_fuel_type.json" -UK_LCFS_NTS_BUS_USE_RESOURCE = "nts_bus_use_frequency.json" UK_LCFS_DFT_BUS_VALUE_RESOURCE = "dft_bus_value_anchors.json" +# The register names this module as a reader of dft_bus_journeys.json. +UK_LCFS_DFT_BUS_JOURNEYS_RESOURCE = UK_DFT_BUS_JOURNEYS_RESOURCE UK_LCFS_DEVOLVED_BUS_FINANCE_RESOURCE = "devolved_bus_finance.json" UK_LCFS_VENDORED_RESOURCES = ( UK_LCFS_ROAD_FUEL_RESOURCE, UK_LCFS_LICENSED_CARS_RESOURCE, - UK_LCFS_NTS_BUS_USE_RESOURCE, UK_LCFS_DFT_BUS_VALUE_RESOURCE, + UK_LCFS_DFT_BUS_JOURNEYS_RESOURCE, UK_LCFS_DEVOLVED_BUS_FINANCE_RESOURCE, UK_NEED_ENERGY_FACTS_RESOURCE, UK_DESNZ_DOMESTIC_ENERGY_RESOURCE, UK_QEP_ENERGY_PRICES_RESOURCE, ) -#: Columns a declared rake levels; the support clip and the committed support -#: bounds leave them alone. +#: Columns a declared rake or pricing step levels (energy in kWh to the NEED +#: shape at the DESNZ level; bus fares as journeys times the published +#: yield, microcosm#930); the committed support bounds leave them alone. UK_LCFS_RAKED_COLUMNS = frozenset( { "electricity_consumption", @@ -192,9 +189,6 @@ UK_OBR_FUEL_DUTY_RECEIPTS_CONCEPT = "obr.fuel_duty.receipts" UK_OBR_CARS_CATEGORY = "cars" UK_OBR_TOTAL_CATEGORY = "total" -#: Identity-keyed uniforms for the positive-regime bus fare draw of user -#: households the chain drew at zero (salted apart from the incidence draw). -UK_LCFS_BUS_FARE_POSITIVE_SALT = "lcfs_bus_fare_positive" #: Columns whose level a declared rake sets; the support clip never touches them. UK_LCFS_DEFAULT_SUPPORT_CLIP_EXEMPT = frozenset( {"electricity_consumption", "gas_consumption", "domestic_energy_consumption"} @@ -256,8 +250,7 @@ class UKLCFSConsumptionResult: support_clip: UKSupportClipReceipt donor_uprating: Mapping[str, Any] | None = None fuel_flag: Mapping[str, Any] | None = None - bus_use_incidence: Mapping[str, Any] | None = None - bus_fare_rake: Mapping[str, Any] | None = None + bus_pricing: Mapping[str, Any] | None = None energy_pricing: Mapping[str, Any] | None = None energy_rake: Mapping[str, Any] | None = None fuel_litres_audit: Mapping[str, Any] | None = None @@ -271,10 +264,8 @@ def evidence(self) -> dict[str, object]: evidence["donor_uprating"] = dict(self.donor_uprating) if self.fuel_flag is not None: evidence["has_fuel_consumption"] = dict(self.fuel_flag) - if self.bus_use_incidence is not None: - evidence["bus_use_incidence"] = dict(self.bus_use_incidence) - if self.bus_fare_rake is not None: - evidence["bus_fare_rake"] = dict(self.bus_fare_rake) + if self.bus_pricing is not None: + evidence["bus_pricing"] = dict(self.bus_pricing) if self.energy_pricing is not None: evidence["energy_pricing"] = dict(self.energy_pricing) if self.energy_rake is not None: @@ -354,24 +345,11 @@ def __call__(self, frame: Frame) -> Frame: recipient_weights=weights, ice_share_receipt=ice_share_receipt, ) - incidence = lcfs_bus_use_incidence(self.stage, frame) - fare_rake_regions = bus_fare_rake_regions(self.stage) imputation = impute_lcfs_consumption( donor, recipient, seed=_operation_seed(self.stage, "fit_weighted_qrf_chain"), n_estimators=_qrf_n_estimators(self.stage), - bus_users=None if incidence is None else incidence.household_user, - bus_scope=None - if incidence is None - else np.isin(recipient["region"].astype(str).to_numpy(), fare_rake_regions), - bus_positive_uniforms=None - if incidence is None - else stable_identity_uniforms( - frame.table("household")["household_id"].to_numpy(), - seed=_operation_seed(self.stage, "assign_bus_use_incidence"), - salt=UK_LCFS_BUS_FARE_POSITIVE_SALT, - ), ) clip_result = support_clip_to_donor( imputation.draws, donor, exempt=support_clip_exempt(self.stage) @@ -389,12 +367,8 @@ def __call__(self, frame: Frame) -> Frame: weights=weights, iterations=_recipient_energy_rake_iterations(self.stage), ) - household_draws, bus_fare_rake_receipt = lcfs_bus_fare_rake( - self.stage, - household_draws, - frame, - recipient=recipient, - users=None if incidence is None else incidence.household_user, + household_draws, bus_pricing_receipt = lcfs_bus_fare_pricing( + self.stage, household_draws, frame ) household_draws["domestic_energy_consumption"] = ( household_draws["electricity_consumption"] @@ -434,10 +408,7 @@ def __call__(self, frame: Frame) -> Frame: support_clip=clip_result.receipt, donor_uprating=uprating_receipt, fuel_flag=fuel_flag_receipt, - bus_use_incidence=None - if incidence is None - else {**incidence.receipt, **imputation.bus_fare_receipt}, - bus_fare_rake=bus_fare_rake_receipt, + bus_pricing=bus_pricing_receipt, energy_pricing=None if energy is None else energy.receipt, energy_rake=energy_rake_receipt, fuel_litres_audit=litres_audit, @@ -458,7 +429,6 @@ def checkpoint_metadata(self) -> dict[str, object]: class UKLCFSConsumptionImputationResult: draws: pd.DataFrame fit_weight_records: tuple[FitWeightRecord, ...] - bus_fare_receipt: Mapping[str, Any] = field(default_factory=dict) def fuel_litres_audit( @@ -761,95 +731,60 @@ def support_clip_exempt(stage: SourceStageSpec) -> set[str]: return set(UK_LCFS_DEFAULT_SUPPORT_CLIP_EXEMPT) -def lcfs_bus_use_incidence( - stage: SourceStageSpec, frame: Frame -) -> BusUseIncidenceResult | None: - """Draw the declared local-bus use incidence on the recipient frame.""" - - parameters = incidence_operation(stage) - if parameters is None: - return None - if parameters.get("output") != "uses_local_bus": - raise ValueError("assign_bus_use_incidence must output uses_local_bus.") - shares, shares_receipt = nts_band_shares(parameters) - result = assign_bus_use_incidence( - frame.table("person"), - frame.table("household"), - household_weights=frame.weights_for("household").values, - shares=shares, - seed=int(parameters["seed"]), - ) - return BusUseIncidenceResult( - household_user=result.household_user, - person_band=result.person_band, - receipt={"nts": shares_receipt, **result.receipt}, - ) - - -def bus_fare_rake_regions(stage: SourceStageSpec) -> tuple[str, ...]: - """The FRS regions a declared bus-fare rake cell levels. +def bus_pricing_operation(stage: SourceStageSpec) -> Mapping[str, Any] | None: + """The stage's declared ``price_bus_journeys`` parameters, if any.""" - The incidence override (positive-regime fill for users, zero for - non-users) is imposed only there: a positive-regime amount is a - diary-positive fortnight annualised, so without the rake to level it the - override would overstate a region's fares several-fold. Where no - publisher receipts exist (Wales) the chain's raw draw stands. - """ - - regions: list[str] = [] - for parameters in rake_operations(stage): - if "bus_fare_spending" not in [str(c) for c in parameters["columns"]]: - continue - for cell in parameters["cells"]: - regions.extend(str(region) for region in cell["regions"]) - return tuple(dict.fromkeys(regions)) + for operation in stage.operations: + if operation.kind == PRICE_BUS_JOURNEYS_KIND: + return {"kind": operation.kind, **operation.parameters} + return None -def lcfs_bus_fare_rake( - stage: SourceStageSpec, - household_draws: pd.DataFrame, - frame: Frame, - *, - recipient: pd.DataFrame, - users: np.ndarray | None, +def lcfs_bus_fare_pricing( + stage: SourceStageSpec, household_draws: pd.DataFrame, frame: Frame ) -> tuple[pd.DataFrame, dict[str, Any] | None]: - """Apply every declared ``rake_to_vendored_facts`` operation on the stage.""" + """Replace the priced regions' bus fares with journeys times the published yield. + + The chain's raw draw (clipped to donor support) stands where no area + prices (Wales); everywhere else the emitted value is the sum over the + household's non-eligible persons of their ``nts_bus_travel`` journeys + times boardings per resident trip times the yield per fare-paying + boarding (microcosm#930). The chain conditioned later targets on the raw + draw, which the receipt states. + """ - operations = rake_operations(stage) - if not operations: + parameters = bus_pricing_operation(stage) + if parameters is None: return household_draws, None + column = str(parameters["column"]) + if column not in household_draws: + raise ValueError( + f"price_bus_journeys names {column!r}, which the chain did not draw." + ) + prices = bus_fare_prices(parameters, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + trips_columns = { + str(k): str(v) for k, v in dict(parameters["trips_columns"]).items() + } household = frame.table("household") - person = frame.table("person") - persons = ( - person.groupby("person_household_id") - .size() - .reindex(household["household_id"]) - .fillna(0.0) - .to_numpy(dtype=float) + fares, priced, receipt = price_bus_journeys( + frame.table("person"), + household, + prices=prices, + trips_columns=trips_columns, + eligibility_column=str(parameters["eligibility_column"]), + household_weights=frame.weights_for("household").values, + raw_household_fares=household_draws[column].to_numpy(dtype=float), ) - receipts: list[dict[str, Any]] = [] - raked = household_draws - for parameters in operations: - cells = resolve_cells(parameters, allowed_resources=UK_LCFS_VENDORED_RESOURCES) - income_key = parameters.get("quintile_income") - raked, receipt = rake_to_facts( - raked, - columns=[str(column) for column in parameters["columns"]], - cells=cells, - region=recipient["region"].astype(str).to_numpy(), - weights=frame.weights_for("household").values - if bool(parameters.get("weighted", True)) - else None, - scope=str(parameters["scope"]), - users=users, - quintile_income=None - if income_key is None - else _numeric(recipient[str(income_key)]).to_numpy(dtype=float), - household_persons=persons, - iterations=int(parameters.get("iterations", 1)), - ) - receipts.append(receipt) - return raked, receipts[0] if len(receipts) == 1 else {"operations": receipts} + priced_draws = household_draws.copy() + priced_draws[column] = fares + return priced_draws, { + "operation": PRICE_BUS_JOURNEYS_KIND, + "column": column, + "chain_conditioned_on": "raw_draw", + "households_priced": int(priced.sum()), + **prices.receipt, + **receipt, + } def lcfs_donor_uprating( @@ -1180,21 +1115,12 @@ def impute_lcfs_consumption( *, seed: int, n_estimators: int, - bus_users: np.ndarray | None = None, - bus_positive_uniforms: np.ndarray | None = None, - bus_scope: np.ndarray | None = None, ) -> UKLCFSConsumptionImputationResult: - """Chain-draw the targets; optionally impose the bus-use incidence. - - With ``bus_users`` (one bool per recipient) the ``bus_fare_spending`` - draw is overridden after the chain step: non-user households take zero, - user households drawn at zero take the step's positive-regime draw at - their identity-keyed ``bus_positive_uniforms`` quantile, and user - households drawn positive keep their draw. ``bus_scope`` limits the - override to the households a declared fare rake levels afterwards (the - regions with published receipts); outside it the raw draw stands. The - chain itself keeps conditioning on the raw prior draw, so later targets - are unchanged. + """Chain-draw the targets in the declared order. + + ``bus_fare_spending`` stays a chain target so later targets condition on + the same raw draw; the emitted fares are then replaced by the priced + value where an area prices (microcosm#930). """ from microcosm.fit import RegimeGatedQRF @@ -1212,7 +1138,6 @@ def impute_lcfs_consumption( raw = pd.DataFrame(index=recipient_encoded.index) draws = pd.DataFrame(index=recipient_encoded.index) fit_records: list[FitWeightRecord] = [] - bus_receipt: dict[str, Any] = {} for target in UK_LCFS_CONSUMPTION_TARGET_COLUMNS: features = recipient_encoded.loc[:, list(predictors)] result = model.fit_draw_next( @@ -1224,65 +1149,13 @@ def impute_lcfs_consumption( ) raw[target] = result.raw_draw draws[target] = result.raw_draw - if target == "bus_fare_spending" and bus_users is not None: - draws[target], bus_receipt = _impose_bus_use_incidence( - result, - features.join(raw.drop(columns=[target])), - raw_draw=np.asarray(result.raw_draw, dtype=float), - users=np.asarray(bus_users, dtype=bool), - uniforms=bus_positive_uniforms, - scope=None if bus_scope is None else np.asarray(bus_scope, dtype=bool), - ) fit_records.append( FitWeightRecord( f"{UK_LCFS_CONSUMPTION_FIT_NAME}:{target}", result.weight_kind ) ) state = result.state - return UKLCFSConsumptionImputationResult(draws, tuple(fit_records), bus_receipt) - - -def _impose_bus_use_incidence( - step: Any, - features: pd.DataFrame, - *, - raw_draw: np.ndarray, - users: np.ndarray, - uniforms: np.ndarray | None, - scope: np.ndarray | None = None, -) -> tuple[np.ndarray, dict[str, Any]]: - if uniforms is None: - raise ValueError("bus incidence needs identity-keyed positive-draw uniforms.") - if len(users) != len(raw_draw) or len(uniforms) != len(raw_draw): - raise ValueError("bus incidence inputs must align with the recipients.") - in_scope = np.ones(len(raw_draw), dtype=bool) if scope is None else scope - if len(in_scope) != len(raw_draw): - raise ValueError("bus incidence scope must align with the recipients.") - fitted = step.fitted - if fitted is None: - raise ValueError("the bus_fare_spending chain step exposes no fitted view.") - positive = fitted.predict_positive_from_uniforms( - features, quantiles={"bus_fare_spending": np.asarray(uniforms, dtype=float)} - )["bus_fare_spending"].to_numpy(dtype=float) - drawn_positive = raw_draw > 0 - filled = in_scope & users & ~drawn_positive - imposed = np.where(users, np.where(drawn_positive, raw_draw, positive), 0.0) - adjusted = np.where(in_scope, imposed, raw_draw) - return adjusted, { - "regime": str(getattr(step.regime, "name", step.regime)), - "positive_draw_salt": UK_LCFS_BUS_FARE_POSITIVE_SALT, - "chain_conditioned_on": "raw_draw", - "households": int(len(raw_draw)), - "households_in_scope": int(in_scope.sum()), - "households_outside_scope_keep_raw_draw": int((~in_scope).sum()), - "users": int(users.sum()), - "users_in_scope": int((in_scope & users).sum()), - "users_drawn_positive": int((in_scope & users & drawn_positive).sum()), - "users_filled_from_positive_regime": int(filled.sum()), - "non_users_zeroed": int((in_scope & ~users & drawn_positive).sum()), - "positive_share_before": float(drawn_positive.mean()) if len(raw_draw) else 0.0, - "positive_share_after": float((adjusted > 0).mean()) if len(raw_draw) else 0.0, - } + return UKLCFSConsumptionImputationResult(draws, tuple(fit_records)) def support_clip_to_donor( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py new file mode 100644 index 000000000..a907dfb10 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py @@ -0,0 +1,1438 @@ +"""Local-bus travel imputed onto the UK spine from the National Travel Survey. + +The ``nts_bus_travel`` stage (microcosm#930) reads the NTS microdata (UKDS +SN 5340, End User Licence: Household, Individual and Trip tables linked by +``HouseholdID`` and ``IndividualID``; England residents only since 2013) and +imputes, per person of the FRS spine, the interview frequency-of-use band for +local buses, the annual local-bus trips that band carries in the diary, split +into the two published series (bus in London, other local bus), and the +statutory concessionary-travel eligibility of the person's area. It replaces +the take-up style incidence draw of microcosm#890 (published shares only) with +a conditional model (region, age band, sex, cars, household size, income band) +fitted on the survey, so that the lcfs stage can price journeys at a published +yield instead of raking fares to the receipts it is calibrated to. + +Why the band, not the diary count: a seven-day diary annualised per person is +zero for about three quarters of people and a multiple of 52 for the rest, +right in aggregate and wrong in distribution. The interview band (the variable +behind DfT table NTS0313) carries incidence and level; the diary supplies the +mean annual trips per person in each band and residence group (London / rest +of England), weighted by W5 x JJXSC (short walks grossed) over W2 persons and +annualised by 52.14. If the deposited extract carries no band variable the +stage falls back to the published NTS0313 / NTS0621 shares (the #890 draw) and +scales declared band midpoints to the published trip rate; the receipt says +which path ran. + +Every publisher value the stage checks itself against comes from vendored +Chronicle rows (``nts_trip_rates.json``, ``nts_bus_use_frequency.json``, +``nts_car_availability.json``); nothing derived from the licensed rows is +committed. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from dataclasses import dataclass, field +from pathlib import Path +from typing import Any + +import numpy as np +import pandas as pd + +from microcosm.build.gates import FitWeightRecord +from microcosm.build.source_manifest import SourceStageSpec +from microcosm.build.stochastic_assignment import stable_identity_uniforms +from microcosm.build.uk_runtime.bus_use_incidence import ( + assign_bus_use_incidence, + nts_band_shares, +) +from microcosm.build.uk_runtime.frs_spine import read_pinned_tab +from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows +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.support_clip import ( + UKSupportClipReceipt, + support_clip_to_donor_with_receipt, +) +from microcosm.frame import Frame +from microcosm.frame.rules import assert_rules_engine_country + +UK_NTS_BUS_TRAVEL_STAGE_NAME = "nts_bus_travel" +UK_NTS_HOUSEHOLD_TAB_ROLE = "nts_household_tab" +UK_NTS_INDIVIDUAL_TAB_ROLE = "nts_individual_tab" +UK_NTS_TRIP_TAB_ROLE = "nts_trip_tab" + +CLEAN_NTS_TRAVEL_TABLES_KIND = "clean_nts_travel_tables" +IMPUTE_BUS_USE_BAND_KIND = "impute_bus_use_band" +ASSIGN_TRIPS_FROM_BAND_MEANS_KIND = "assign_trips_from_band_means" +ASSIGN_BUS_PASS_ELIGIBILITY_KIND = "assign_bus_pass_eligibility" + +BUS_IN_LONDON = "bus_in_london" +OTHER_LOCAL_BUS = "other_local_bus" +SERIES: tuple[str, str] = (BUS_IN_LONDON, OTHER_LOCAL_BUS) +SERIES_TRIP_COLUMNS: Mapping[str, str] = { + BUS_IN_LONDON: "bus_in_london_trips", + OTHER_LOCAL_BUS: "other_local_bus_trips", +} +SERIES_TRIP_RATE_CONCEPTS: Mapping[str, str] = { + BUS_IN_LONDON: "dft.bus_in_london_trips_per_person", + OTHER_LOCAL_BUS: "dft.other_local_bus_trips_per_person", +} + +BAND_COLUMN = "local_bus_use_band" +TRIPS_COLUMN = "local_bus_trips" +ELIGIBLE_COLUMN = "bus_pass_eligible" +HOUSEHOLD_TRIPS_COLUMN = "household_local_bus_trips" +UK_NTS_PERSON_OUTPUT_COLUMNS: tuple[str, ...] = ( + BAND_COLUMN, + SERIES_TRIP_COLUMNS[BUS_IN_LONDON], + SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], + TRIPS_COLUMN, + ELIGIBLE_COLUMN, +) +UK_NTS_HOUSEHOLD_OUTPUT_COLUMNS: tuple[str, ...] = (HOUSEHOLD_TRIPS_COLUMN,) +UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS: tuple[str, ...] = ( + *UK_NTS_PERSON_OUTPUT_COLUMNS, + *UK_NTS_HOUSEHOLD_OUTPUT_COLUMNS, +) +#: The columns the person-level support clip covers (band and trips). +UK_NTS_SUPPORT_CLIP_COLUMNS: tuple[str, ...] = ( + BAND_COLUMN, + SERIES_TRIP_COLUMNS[BUS_IN_LONDON], + SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], + TRIPS_COLUMN, +) +#: Vendored resources the stage reads (the register's consumer truthfulness). +UK_NTS_TRIP_RATES_RESOURCE = "nts_trip_rates.json" +UK_NTS_CAR_AVAILABILITY_RESOURCE = "nts_car_availability.json" +UK_NTS_BUS_USE_FREQUENCY_RESOURCE = "nts_bus_use_frequency.json" +UK_NTS_BUS_TRAVEL_VENDORED_RESOURCES: frozenset[str] = frozenset( + { + UK_NTS_TRIP_RATES_RESOURCE, + UK_NTS_CAR_AVAILABILITY_RESOURCE, + UK_NTS_BUS_USE_FREQUENCY_RESOURCE, + } +) + +#: Ordinal bands, 0 = the non-user band. Higher is more frequent. Ids match the +#: NTS0313 band ids declared on the incidence resource so the fact checks join +#: on the same vocabulary. +BAND_IDS: tuple[str, ...] = ( + "less_than_once_a_year_or_never", + "once_or_twice_a_year", + "less_than_monthly_more_than_twice_a_year", + "once_or_twice_a_month", + "less_than_weekly_more_than_twice_a_month", + "once_or_twice_a_week", + "three_or_more_times_a_week", +) +NON_USER_BAND = 0 +MAX_BAND = len(BAND_IDS) - 1 +BAND_SALT_QUANTILE = "nts_bus_use_band_quantile" +BAND_SALT_SIGN = "nts_bus_use_band_sign" +WEEKS_IN_YEAR = 52.14 +LONDON_GROUP = "london" +REST_OF_ENGLAND_GROUP = "rest_of_england" +RESIDENCE_GROUPS: tuple[str, str] = (LONDON_GROUP, REST_OF_ENGLAND_GROUP) +FREQUENCY_SOURCE_INTERVIEW = "interview_band" +FREQUENCY_SOURCE_PUBLISHED_SHARES = "published_shares" + + +class NTSBusTravelError(ValueError): + """Raised when the NTS tabs or the declaration do not carry what the stage needs.""" + + +# -------------------------------------------------------------------------- +# Declaration readers +# -------------------------------------------------------------------------- + + +def _artifact(stage: SourceStageSpec, role: str) -> Mapping[str, Any]: + for artifact in stage.artifacts: + if artifact.get("role") == role: + return artifact + raise NTSBusTravelError(f"{stage.stage} declares no {role!r} artifact.") + + +def _operation(stage: SourceStageSpec, kind: str) -> Mapping[str, Any]: + for operation in stage.operations: + if operation.kind == kind: + return dict(operation.parameters) + raise NTSBusTravelError(f"{stage.stage} declares no {kind!r} operation.") + + +def _optional_operation(stage: SourceStageSpec, kind: str) -> Mapping[str, Any] | None: + for operation in stage.operations: + if operation.kind == kind: + return dict(operation.parameters) + return None + + +@dataclass(frozen=True) +class NTSColumns: + """The declared NTS column names and codes (one place to correct the codebook).""" + + household_id: str + individual_id: str + trip_id: str + survey_year: str + region: str + income_band: str + cars: str + household_size: str + household_weight: str + age_band: str + sex: str + frequency: str | None + main_mode: str + trip_weight: str + short_walk_multiplier: str + region_codes: Mapping[int, str] + london_region_code: int + income_band_codes: Mapping[int, int] + age_band_edges: tuple[int, ...] + female_code: int + mode_codes: Mapping[str, int] + frequency_codes: Mapping[int, int] + survey_years: tuple[int, ...] + + @classmethod + def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: + columns = _mapping(parameters.get("columns"), "derive.columns") + codes = _mapping(parameters.get("codes"), "derive.codes") + required = ( + "household_id", + "individual_id", + "trip_id", + "survey_year", + "region", + "income_band", + "cars", + "household_size", + "household_weight", + "age_band", + "sex", + "main_mode", + "trip_weight", + "short_walk_multiplier", + ) + missing = [name for name in required if not isinstance(columns.get(name), str)] + if missing: + raise NTSBusTravelError(f"derive.columns lacks {missing}.") + frequency = columns.get("frequency") + if frequency is not None and not isinstance(frequency, str): + raise NTSBusTravelError( + "derive.columns.frequency must be a string or absent." + ) + region_codes = { + int(code): str(name) + for code, name in _mapping(codes.get("region"), "codes.region").items() + } + london = [code for code, name in region_codes.items() if name == "LONDON"] + if len(london) != 1: + raise NTSBusTravelError("codes.region must map exactly one code to LONDON.") + income_codes = { + int(code): int(band) + for code, band in _mapping( + codes.get("income_band"), "codes.income_band" + ).items() + } + if sorted(set(income_codes.values())) != [1, 2, 3]: + raise NTSBusTravelError( + "codes.income_band must map onto the bands 1, 2, 3." + ) + edges = tuple(int(e) for e in parameters.get("age_band_edges", ())) + if len(edges) < 2 or list(edges) != sorted(edges) or edges[0] != 0: + raise NTSBusTravelError( + "age_band_edges must be an ascending list of lower bounds starting at 0." + ) + mode_codes = { + str(series): int(code) + for series, code in _mapping( + codes.get("main_mode"), "codes.main_mode" + ).items() + } + if set(mode_codes) != set(SERIES): + raise NTSBusTravelError( + f"codes.main_mode must name exactly the series {list(SERIES)}." + ) + frequency_codes = { + int(code): int(band) + for code, band in _mapping( + codes.get("frequency", {}), "codes.frequency" + ).items() + } + if frequency is not None: + if sorted(set(frequency_codes.values())) != list(range(len(BAND_IDS))): + raise NTSBusTravelError( + "codes.frequency must map the interview codes onto every band " + f"ordinal 0..{MAX_BAND}." + ) + years = tuple(int(y) for y in parameters.get("survey_years", ())) + if not years: + raise NTSBusTravelError("derive.survey_years must name at least one year.") + return cls( + household_id=columns["household_id"].lower(), + individual_id=columns["individual_id"].lower(), + trip_id=columns["trip_id"].lower(), + survey_year=columns["survey_year"].lower(), + region=columns["region"].lower(), + income_band=columns["income_band"].lower(), + cars=columns["cars"].lower(), + household_size=columns["household_size"].lower(), + household_weight=columns["household_weight"].lower(), + age_band=columns["age_band"].lower(), + sex=columns["sex"].lower(), + frequency=None if frequency is None else frequency.lower(), + main_mode=columns["main_mode"].lower(), + trip_weight=columns["trip_weight"].lower(), + short_walk_multiplier=columns["short_walk_multiplier"].lower(), + region_codes=region_codes, + london_region_code=int(london[0]), + income_band_codes=income_codes, + age_band_edges=edges, + female_code=int(codes.get("female", 2)), + mode_codes=mode_codes, + frequency_codes=frequency_codes, + survey_years=years, + ) + + +def _mapping(value: object, label: str) -> Mapping[str, Any]: + if not isinstance(value, Mapping): + raise NTSBusTravelError(f"{label} must be a mapping.") + return value + + +# -------------------------------------------------------------------------- +# Donor cleaning +# -------------------------------------------------------------------------- + + +def _lower(table: pd.DataFrame) -> pd.DataFrame: + out = table.copy() + out.columns = [str(c).lower() for c in out.columns] + return out + + +def _require(table: pd.DataFrame, columns: Sequence[str], label: str) -> None: + missing = [c for c in columns if c not in table.columns] + if missing: + raise NTSBusTravelError( + f"NTS {label} table lacks the declared columns {missing}; correct the " + "stage's derive.columns against the deposited lookup tables." + ) + + +def age_band_ordinal( + ages: Sequence[float] | np.ndarray, edges: Sequence[int] +) -> np.ndarray: + """The declared age band (0-based ordinal) of each age.""" + + values = np.asarray(ages, dtype=float) + bounds = np.asarray(edges[1:], dtype=float) + return np.searchsorted(bounds, values, side="right").astype(np.int64) + + +@dataclass(frozen=True) +class NTSDonor: + """The cleaned NTS person donor and its diary trips.""" + + person: pd.DataFrame + frequency_source: str + receipt: dict[str, Any] + + +def clean_nts_travel_tables( + household: pd.DataFrame, + individual: pd.DataFrame, + trip: pd.DataFrame, + *, + columns: NTSColumns, + cars_clip: tuple[int, int] = (0, 5), +) -> NTSDonor: + """One row per NTS individual of the declared survey years, with predictors. + + Columns: ``region`` (FRS region name via the declared GOR codes), + ``residence_group`` (``london`` / ``rest_of_england``), ``age_band`` + (declared ordinal), ``is_female``, ``num_vehicles`` (clipped), ``household_size``, + ``income_band`` (1..3), ``weight`` (W2, the diary household weight), the + interview ``local_bus_use_band`` when the extract carries it, and the + annual diary trips per series (52.14 x sum of trip weight x short-walk + multiplier over the person's trips whose main mode is that series). + """ + + hh = _lower(household) + ind = _lower(individual) + tr = _lower(trip) + _require( + hh, + ( + columns.household_id, + columns.survey_year, + columns.region, + columns.income_band, + columns.cars, + columns.household_size, + columns.household_weight, + ), + "household", + ) + _require( + ind, + (columns.individual_id, columns.household_id, columns.age_band, columns.sex), + "individual", + ) + _require( + tr, + ( + columns.trip_id, + columns.individual_id, + columns.main_mode, + columns.trip_weight, + columns.short_walk_multiplier, + ), + "trip", + ) + years = pd.to_numeric(hh[columns.survey_year], errors="coerce") + hh = hh.loc[years.isin(columns.survey_years)].copy() + if hh.empty: + raise NTSBusTravelError( + f"NTS household table has no rows for survey years {columns.survey_years}." + ) + weight = pd.to_numeric(hh[columns.household_weight], errors="coerce") + hh = hh.loc[weight.notna() & (weight > 0)].copy() + region_code = pd.to_numeric(hh[columns.region], errors="coerce") + region = region_code.map(columns.region_codes) + unmapped = int(region.isna().sum()) + hh = hh.loc[region.notna()].copy() + hh["region"] = region.loc[hh.index].astype(str) + hh["residence_group"] = np.where( + pd.to_numeric(hh[columns.region], errors="coerce") + == columns.london_region_code, + LONDON_GROUP, + REST_OF_ENGLAND_GROUP, + ) + income_code = pd.to_numeric(hh[columns.income_band], errors="coerce") + income = income_code.map(columns.income_band_codes) + income_missing = int(income.isna().sum()) + hh = hh.loc[income.notna()].copy() + hh["income_band"] = income.loc[hh.index].astype(np.int64) + cars = pd.to_numeric(hh[columns.cars], errors="coerce").fillna(0.0) + hh["num_vehicles"] = cars.clip(lower=cars_clip[0], upper=cars_clip[1]).astype( + np.int64 + ) + hh["household_size"] = ( + pd.to_numeric(hh[columns.household_size], errors="coerce") + .fillna(1.0) + .clip(lower=1.0) + ).astype(np.int64) + hh["weight"] = pd.to_numeric(hh[columns.household_weight], errors="coerce").astype( + float + ) + hh_keep = hh[ + [ + columns.household_id, + columns.survey_year, + "region", + "residence_group", + "income_band", + "num_vehicles", + "household_size", + "weight", + ] + ].rename(columns={columns.survey_year: "survey_year"}) + person = ind[ + [columns.individual_id, columns.household_id, columns.age_band, columns.sex] + ] + person = person.merge(hh_keep, on=columns.household_id, how="inner") + age_code = pd.to_numeric(person[columns.age_band], errors="coerce") + # The NTS band code is 1-based and ordered like the declared edges. + person["age_band"] = (age_code - 1).clip( + lower=0, upper=len(columns.age_band_edges) - 1 + ) + person = person.loc[age_code.notna()].copy() + person["age_band"] = person["age_band"].astype(np.int64) + sex = pd.to_numeric(person[columns.sex], errors="coerce") + person["is_female"] = (sex == columns.female_code).astype(np.int64) + frequency_source = FREQUENCY_SOURCE_PUBLISHED_SHARES + if columns.frequency is not None and columns.frequency in ind.columns: + freq = pd.to_numeric( + ind.set_index(columns.individual_id)[columns.frequency], errors="coerce" + ) + band = person[columns.individual_id].map(freq).map(columns.frequency_codes) + known = band.notna() + person = person.loc[known].copy() + person[BAND_COLUMN] = band.loc[person.index].astype(np.int64) + frequency_source = FREQUENCY_SOURCE_INTERVIEW + # Diary trips per person per series, annualised. + tr = tr.loc[tr[columns.individual_id].isin(person[columns.individual_id])].copy() + mode = pd.to_numeric(tr[columns.main_mode], errors="coerce") + trip_weight = pd.to_numeric(tr[columns.trip_weight], errors="coerce").fillna(0.0) + multiplier = pd.to_numeric( + tr[columns.short_walk_multiplier], errors="coerce" + ).fillna(0.0) + counted = trip_weight * multiplier + for series in SERIES: + code = columns.mode_codes[series] + per_person = ( + counted.where(mode == code, 0.0).groupby(tr[columns.individual_id]).sum() + ) + person[SERIES_TRIP_COLUMNS[series]] = ( + person[columns.individual_id] + .map(per_person) + .fillna(0.0) + .to_numpy(dtype=float) + * WEEKS_IN_YEAR + ) + person[TRIPS_COLUMN] = ( + person[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + + person[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]] + ) + person = person.rename( + columns={ + columns.individual_id: "individual_id", + columns.household_id: "household_id", + } + ) + keep = [ + "individual_id", + "household_id", + "survey_year", + "region", + "residence_group", + "age_band", + "is_female", + "num_vehicles", + "household_size", + "income_band", + "weight", + SERIES_TRIP_COLUMNS[BUS_IN_LONDON], + SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], + TRIPS_COLUMN, + ] + if frequency_source == FREQUENCY_SOURCE_INTERVIEW: + keep.append(BAND_COLUMN) + person = person[keep].reset_index(drop=True) + if person.empty: + raise NTSBusTravelError("NTS cleaning left no donor persons.") + receipt = { + "survey_years": list(columns.survey_years), + "households": int(len(hh_keep)), + "persons": int(len(person)), + "weighted_persons": float(person["weight"].sum()), + "households_unmapped_region": unmapped, + "households_missing_income_band": income_missing, + "frequency_source": frequency_source, + "frequency_column": columns.frequency, + "annualisation_weeks": WEEKS_IN_YEAR, + "trips_per_person": { + series: float(np.average(person[column], weights=person["weight"])) + for series, column in SERIES_TRIP_COLUMNS.items() + }, + } + return NTSDonor(person=person, frequency_source=frequency_source, receipt=receipt) + + +# -------------------------------------------------------------------------- +# Recipient predictors +# -------------------------------------------------------------------------- + +UK_NTS_ENGINE_PREDICTORS: tuple[str, ...] = ("household_gross_income",) + + +def _enum_name(value: object) -> str: + name = getattr(value, "name", None) + return str(name if name is not None else value) + + +def recipient_predictors( + frame: Frame, + engine: object, + *, + columns: NTSColumns, + income_band_edges: Sequence[float], + region_remap: Mapping[str, str], + cars_clip: tuple[int, int] = (0, 5), +) -> pd.DataFrame: + """Person-grain predictors of the FRS spine in the donor's vocabulary.""" + + person = frame.table("person") + household = frame.table("household") + for column in ("person_id", "person_household_id", "age", "gender"): + if column not in person: + raise NTSBusTravelError(f"recipient person table lacks {column!r}.") + for column in ("household_id", "region", "num_vehicles"): + if column not in household: + raise NTSBusTravelError( + f"recipient household table lacks {column!r}" + + (" (the was_wealth draw)." if column == "num_vehicles" else ".") + ) + materialized = engine.materialize( + frame, UK_NTS_ENGINE_PREDICTORS, uk_time_period(frame) + ) + by_household = household.set_index("household_id") + hh_ids = person["person_household_id"].to_numpy() + region = by_household["region"].map(_enum_name).reindex(hh_ids).to_numpy() + if pd.isna(region).any(): + raise NTSBusTravelError( + "every recipient person must map to a household region." + ) + remapped = np.asarray( + [region_remap.get(str(r), str(r)) for r in region], dtype=object + ) + unknown = sorted(set(remapped) - set(columns.region_codes.values())) + if unknown: + raise NTSBusTravelError( + f"recipient regions {unknown} are outside the donor's regions; declare a " + "region_remap for them." + ) + gross = np.asarray(materialized["household_gross_income"], dtype=float) + if len(gross) != len(household): + raise NTSBusTravelError( + "household_gross_income did not materialize at household grain." + ) + gross_by_household = ( + pd.Series(gross, index=by_household.index).reindex(hh_ids).to_numpy() + ) + edges = np.asarray(list(income_band_edges), dtype=float) + income_band = np.searchsorted(edges, gross_by_household, side="right") + 1 + sizes = person.groupby("person_household_id").size() + cars = pd.to_numeric(by_household["num_vehicles"], errors="coerce").fillna(0.0) + result = pd.DataFrame( + { + "person_id": person["person_id"].to_numpy(), + "person_household_id": hh_ids, + "region": remapped, + "residence_region": region, + "residence_group": np.where( + region == "LONDON", LONDON_GROUP, REST_OF_ENGLAND_GROUP + ), + "age": pd.to_numeric(person["age"], errors="coerce").fillna(0.0).to_numpy(), + "age_band": age_band_ordinal( + pd.to_numeric(person["age"], errors="coerce").fillna(0.0).to_numpy(), + columns.age_band_edges, + ), + "is_female": ( + person["gender"].map(_enum_name).str.upper().isin(("FEMALE", "F", "2")) + ) + .astype(np.int64) + .to_numpy(), + "num_vehicles": cars.clip(lower=cars_clip[0], upper=cars_clip[1]) + .reindex(hh_ids) + .astype(np.int64) + .to_numpy(), + "household_size": sizes.reindex(hh_ids).astype(np.int64).to_numpy(), + "income_band": income_band.astype(np.int64), + } + ) + return result + + +# -------------------------------------------------------------------------- +# Band imputation +# -------------------------------------------------------------------------- + +BAND_PREDICTORS: tuple[str, ...] = ( + "age_band", + "is_female", + "num_vehicles", + "household_size", + "income_band", +) + + +def _encode_pair( + donor: pd.DataFrame, recipient: pd.DataFrame +) -> tuple[pd.DataFrame, pd.DataFrame, list[str]]: + base = list(BAND_PREDICTORS) + ["region"] + combined = pd.concat( + [donor[base].reset_index(drop=True), recipient[base].reset_index(drop=True)], + ignore_index=True, + ) + encoded = pd.get_dummies( + combined, columns=["region"], drop_first=False, dtype=float + ) + encoded = encoded.reindex(sorted(encoded.columns), axis=1).astype(float) + predictors = list(encoded.columns) + donor_encoded = encoded.iloc[: len(donor)].copy().reset_index(drop=True) + recipient_encoded = encoded.iloc[len(donor) :].copy().reset_index(drop=True) + return donor_encoded, recipient_encoded, predictors + + +@dataclass(frozen=True) +class BandImputation: + band: np.ndarray + receipt: dict[str, Any] + fit_weight_records: tuple[FitWeightRecord, ...] + + +def impute_bus_use_band( + donor: pd.DataFrame, + recipient: pd.DataFrame, + *, + seed: int, + n_estimators: int, +) -> BandImputation: + """Draw each recipient person's interview band from a QRF fitted on the donor. + + The band is an ordinal with a zero-inflated positive regime (0 = non-user): + the gate draws user / non-user, the positive forest the band among users, + both from identity-keyed uniforms (``stable_identity_uniforms`` on the + person id), so the draw is invariant to ordering and batching. Draws are + rounded to the nearest band. + """ + + from microcosm.fit.qrf import RegimeGatedQRF + + if BAND_COLUMN not in donor: + raise NTSBusTravelError("the donor carries no interview band to fit.") + donor_encoded, recipient_encoded, predictors = _encode_pair(donor, recipient) + train = donor_encoded.copy() + train[BAND_COLUMN] = donor[BAND_COLUMN].to_numpy(dtype=float) + train["weight"] = donor["weight"].to_numpy(dtype=float) + model = RegimeGatedQRF(n_estimators=n_estimators, seed=seed) + fitted = model.fit(train, predictors, [BAND_COLUMN], weights="weight") + ids = recipient["person_id"].to_numpy() + quantiles = stable_identity_uniforms(ids, seed=seed, salt=BAND_SALT_QUANTILE) + signs = stable_identity_uniforms(ids, seed=seed, salt=BAND_SALT_SIGN) + drawn = fitted.predict_from_uniforms( + recipient_encoded, + quantiles={BAND_COLUMN: quantiles}, + sign_uniforms={BAND_COLUMN: signs}, + )[BAND_COLUMN].to_numpy(dtype=float) + band = np.clip(np.rint(drawn), NON_USER_BAND, MAX_BAND).astype(np.int64) + weights = donor["weight"].to_numpy(dtype=float) + donor_shares = _band_shares(donor[BAND_COLUMN].to_numpy(), weights) + receipt = { + "method": "regime_gated_qrf", + "regime": str(fitted.regimes().get(BAND_COLUMN, "")), + "n_estimators": int(n_estimators), + "seed": int(seed), + "predictors": predictors, + "quantile_salt": BAND_SALT_QUANTILE, + "sign_salt": BAND_SALT_SIGN, + "rounding": f"nearest band, clipped to 0..{MAX_BAND}", + "donor_band_shares": donor_shares, + "donor_persons": int(len(donor)), + "recipient_persons": int(len(recipient)), + } + records = ( + FitWeightRecord( + f"{UK_NTS_BUS_TRAVEL_STAGE_NAME}:{BAND_COLUMN}", fitted.weight_kind + ), + ) + return BandImputation(band=band, receipt=receipt, fit_weight_records=records) + + +def _band_shares(bands: np.ndarray, weights: np.ndarray) -> dict[str, float]: + total = float(weights.sum()) + out: dict[str, float] = {} + for ordinal, band_id in enumerate(BAND_IDS): + mask = bands == ordinal + out[band_id] = float(weights[mask].sum() / total) if total > 0 else 0.0 + return out + + +def draw_band_from_published_shares( + recipient: pd.DataFrame, + *, + stage: SourceStageSpec, + household_weights: Mapping[object, float], + seed: int, +) -> BandImputation: + """The fallback: the #890 draw from the vendored NTS0313 / NTS0621 shares.""" + + parameters = _operation(stage, IMPUTE_BUS_USE_BAND_KIND) + fallback = _mapping(parameters.get("fallback"), "impute_bus_use_band.fallback") + shares, shares_receipt = nts_band_shares(fallback) + person = pd.DataFrame( + { + "person_id": recipient["person_id"].to_numpy(), + "person_household_id": recipient["person_household_id"].to_numpy(), + "age": recipient["age"].to_numpy(), + } + ) + household = pd.DataFrame( + {"household_id": sorted(set(person["person_household_id"]))} + ) + weights = np.asarray( + [float(household_weights[h]) for h in household["household_id"]], dtype=float + ) + result = assign_bus_use_incidence( + person, + household, + household_weights=weights, + shares=shares, + seed=seed, + ) + ordinal_by_id = {band_id: ordinal for ordinal, band_id in enumerate(BAND_IDS)} + band = np.asarray( + [ordinal_by_id[str(b)] for b in result.person_band], dtype=np.int64 + ) + receipt = { + "method": "published_shares", + **{k: v for k, v in result.receipt.items() if k != "person_band_shares"}, + "shares_receipt": shares_receipt, + "person_band_shares": result.receipt.get("person_band_shares"), + } + return BandImputation(band=band, receipt=receipt, fit_weight_records=()) + + +# -------------------------------------------------------------------------- +# Trips from band means +# -------------------------------------------------------------------------- + + +def band_means_from_donor( + donor: pd.DataFrame, +) -> tuple[dict[str, dict[str, dict[int, float]]], dict[str, Any]]: + """Weighted mean annual trips per person by series, residence group and band. + + A (group, band) cell with no donor persons falls back to the band's + all-England mean, receipted; a band with no persons at all is refused. + """ + + if BAND_COLUMN not in donor: + raise NTSBusTravelError("band means need the donor's interview band.") + weights = donor["weight"].to_numpy(dtype=float) + bands = donor[BAND_COLUMN].to_numpy() + groups = donor["residence_group"].to_numpy().astype(str) + means: dict[str, dict[str, dict[int, float]]] = {} + fallbacks: list[dict[str, object]] = [] + for series, column in SERIES_TRIP_COLUMNS.items(): + values = donor[column].to_numpy(dtype=float) + means[series] = {} + for group in RESIDENCE_GROUPS: + means[series][group] = {} + for band in range(len(BAND_IDS)): + in_band = bands == band + if not in_band.any(): + raise NTSBusTravelError(f"no donor person is in band {band}.") + cell = in_band & (groups == group) + if weights[cell].sum() > 0: + means[series][group][band] = float( + np.average(values[cell], weights=weights[cell]) + ) + else: + means[series][group][band] = float( + np.average(values[in_band], weights=weights[in_band]) + ) + fallbacks.append({"series": series, "group": group, "band": band}) + receipt = { + "source": "donor_diary_band_means", + "annualisation_weeks": WEEKS_IN_YEAR, + "means": { + series: { + group: {BAND_IDS[b]: v for b, v in by_band.items()} + for group, by_band in by_group.items() + } + for series, by_group in means.items() + }, + "cells_filled_from_all_england": fallbacks, + } + return means, receipt + + +def band_means_from_published_rate( + stage: SourceStageSpec, + *, + band_shares: Mapping[str, float], +) -> tuple[dict[str, dict[str, dict[int, float]]], dict[str, Any]]: + """The fallback: declared band midpoints scaled to the vendored NTS0303 rate. + + ``sum(share_b x midpoint_b)`` is scaled to the published trips per person + of each series; London residents are given the bus-in-London series and + the rest the other-local-bus series (the fallback has no diary to say + otherwise), which the receipt states. + """ + + parameters = _operation(stage, ASSIGN_TRIPS_FROM_BAND_MEANS_KIND) + midpoints = _mapping(parameters.get("band_midpoints"), "band_midpoints") + mid = { + ordinal: float(midpoints[band_id]) + for ordinal, band_id in enumerate(BAND_IDS) + if band_id in midpoints + } + if len(mid) != len(BAND_IDS): + raise NTSBusTravelError("band_midpoints must name every band.") + published = published_trip_rates(parameters) + implied = sum(float(band_shares.get(BAND_IDS[b], 0.0)) * mid[b] for b in mid) + if implied <= 0: + raise NTSBusTravelError( + "the band shares and midpoints imply no local-bus trips." + ) + total_published = sum(published.values()) + scale = total_published / implied + means: dict[str, dict[str, dict[int, float]]] = {series: {} for series in SERIES} + for group in RESIDENCE_GROUPS: + series_here = BUS_IN_LONDON if group == LONDON_GROUP else OTHER_LOCAL_BUS + for series in SERIES: + means[series][group] = { + b: (mid[b] * scale if series == series_here else 0.0) for b in mid + } + receipt = { + "source": "published_rate_scaled_midpoints", + "published_trips_per_person": published, + "implied_trips_per_person_at_midpoints": implied, + "scale": scale, + "series_by_residence_group": { + LONDON_GROUP: BUS_IN_LONDON, + REST_OF_ENGLAND_GROUP: OTHER_LOCAL_BUS, + }, + } + return means, receipt + + +def published_trip_rates(parameters: Mapping[str, Any]) -> dict[str, float]: + """The vendored NTS0303 all-ages trips per person per year, per series.""" + + resource = str(parameters.get("trip_rates_resource") or "") + if resource != UK_NTS_TRIP_RATES_RESOURCE: + raise NTSBusTravelError( + f"trip_rates_resource must be {UK_NTS_TRIP_RATES_RESOURCE!r}, not {resource!r}." + ) + period_value = int(parameters["trip_rates_period_value"]) + out: dict[str, float] = {} + for series, concept in SERIES_TRIP_RATE_CONCEPTS.items(): + # NTS0303 rows carry the survey year as their groupby value; the + # NTS0705a all-households and NTS0601 rows share the concept with + # other groupby values and dimensions. + rows = vendored_rows( + resource, + concept=concept, + period_type="calendar_year", + period_value=period_value, + groupby_value_id=f"cy{period_value}", + dimensions={}, + ) + if len(rows) != 1: + raise NTSBusTravelError( + f"{resource}: expected one NTS0303 row for {concept} {period_value}, " + f"found {len(rows)}." + ) + out[series] = float(rows[0]["value"]) + return out + + +def assign_trips_from_band_means( + band: np.ndarray, + residence_group: np.ndarray, + means: Mapping[str, Mapping[str, Mapping[int, float]]], +) -> dict[str, np.ndarray]: + """Each person's annual trips per series from their band and residence group.""" + + out: dict[str, np.ndarray] = {} + groups = np.asarray(residence_group).astype(str) + for series in SERIES: + values = np.zeros(len(band), dtype=float) + for group in RESIDENCE_GROUPS: + by_band = means[series][group] + lookup = np.asarray( + [by_band[int(b)] for b in range(len(BAND_IDS))], dtype=float + ) + mask = groups == group + values[mask] = lookup[np.asarray(band)[mask]] + out[SERIES_TRIP_COLUMNS[series]] = values + out[TRIPS_COLUMN] = ( + out[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + + out[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]] + ) + return out + + +# -------------------------------------------------------------------------- +# Concessionary eligibility +# -------------------------------------------------------------------------- + + +@dataclass(frozen=True) +class EligibilityRule: + regions: tuple[str, ...] + min_age: int | None + max_age_exclusive: int | None + + def applies(self, ages: np.ndarray) -> np.ndarray: + eligible = np.zeros(len(ages), dtype=bool) + if self.min_age is not None: + eligible |= ages >= self.min_age + if self.max_age_exclusive is not None: + eligible |= ages < self.max_age_exclusive + return eligible + + +def eligibility_rules(parameters: Mapping[str, Any]) -> dict[str, EligibilityRule]: + """The declared statutory rules, keyed by area label.""" + + rules = _mapping(parameters.get("rules"), "assign_bus_pass_eligibility.rules") + out: dict[str, EligibilityRule] = {} + seen: set[str] = set() + for label, rule in rules.items(): + rule = _mapping(rule, f"rules.{label}") + regions = tuple(str(r) for r in rule.get("regions", ())) + if not regions: + raise NTSBusTravelError(f"rules.{label} names no regions.") + dup = seen & set(regions) + if dup: + raise NTSBusTravelError(f"rules.{label} repeats regions {sorted(dup)}.") + seen |= set(regions) + min_age = rule.get("min_age") + max_age = rule.get("max_age_exclusive") + if min_age is None and max_age is None: + raise NTSBusTravelError(f"rules.{label} declares no age bound.") + out[str(label)] = EligibilityRule( + regions=regions, + min_age=None if min_age is None else int(min_age), + max_age_exclusive=None if max_age is None else int(max_age), + ) + return out + + +def assign_bus_pass_eligibility( + ages: np.ndarray, regions: np.ndarray, rules: Mapping[str, EligibilityRule] +) -> tuple[np.ndarray, dict[str, Any]]: + """Eligibility per person from the rule of the person's residence region.""" + + ages = np.asarray(ages, dtype=float) + regions = np.asarray(regions).astype(str) + eligible = np.zeros(len(ages), dtype=bool) + covered = np.zeros(len(ages), dtype=bool) + by_area: dict[str, dict[str, object]] = {} + for label, rule in rules.items(): + mask = np.isin(regions, rule.regions) + eligible[mask] = rule.applies(ages[mask]) + covered |= mask + by_area[label] = { + "regions": list(rule.regions), + "min_age": rule.min_age, + "max_age_exclusive": rule.max_age_exclusive, + "persons": int(mask.sum()), + "eligible": int(eligible[mask].sum()), + } + uncovered = sorted(set(regions[~covered])) + if uncovered: + raise NTSBusTravelError(f"no eligibility rule covers regions {uncovered}.") + return eligible, {"by_area": by_area, "eligible_persons": int(eligible.sum())} + + +# -------------------------------------------------------------------------- +# Fact checks (published values from vendored rows) +# -------------------------------------------------------------------------- + + +def published_band_shares( + stage: SourceStageSpec, +) -> tuple[dict[str, float], dict[str, float], dict[str, Any]]: + """The vendored NTS0313 (all ages) and NTS0621 (60+) band shares, as fractions. + + Read through the stage's declared fallback block (the same declaration the + published-shares draw uses), so the fact check and the fallback agree on + the rows. + """ + + parameters = _operation(stage, IMPUTE_BUS_USE_BAND_KIND) + fallback = _mapping(parameters.get("fallback"), "impute_bus_use_band.fallback") + shares, receipt = nts_band_shares(fallback) + return dict(shares.all_ages), dict(shares.older), receipt + + +def published_car_availability(parameters: Mapping[str, Any]) -> dict[str, float]: + """The vendored NTS0205 England shares (fractions) for the declared year.""" + + resource = str(parameters.get("car_availability_resource") or "") + if resource != UK_NTS_CAR_AVAILABILITY_RESOURCE: + raise NTSBusTravelError( + f"car_availability_resource must be {UK_NTS_CAR_AVAILABILITY_RESOURCE!r}." + ) + period_value = int(parameters["car_availability_period_value"]) + out: dict[str, float] = {} + for key, concept in ( + ("no_car", "dft.households_no_car_share"), + ("one_car", "dft.households_one_car_share"), + ("two_plus_cars", "dft.households_two_plus_cars_share"), + ): + rows = vendored_rows( + resource, + concept=concept, + geography_id="E92000001", + period_type="calendar_year", + period_value=period_value, + ) + if len(rows) != 1: + raise NTSBusTravelError( + f"{resource}: expected one NTS0205 row for {concept} {period_value}." + ) + out[key] = float(rows[0]["value"]) / 100.0 + return out + + +def frame_car_availability( + household: pd.DataFrame, weights: np.ndarray, *, england_regions: Sequence[str] +) -> dict[str, float]: + """The frame's design-weighted no / one / two-plus car shares over England households.""" + + region = household["region"].map(_enum_name).to_numpy().astype(str) + cars = ( + pd.to_numeric(household["num_vehicles"], errors="coerce").fillna(0.0).to_numpy() + ) + mask = np.isin(region, list(england_regions)) + w = np.asarray(weights, dtype=float)[mask] + c = cars[mask] + total = float(w.sum()) + if total <= 0: + raise NTSBusTravelError("no England households to compare car availability on.") + return { + "no_car": float(w[c <= 0].sum() / total), + "one_car": float(w[c == 1].sum() / total), + "two_plus_cars": float(w[c >= 2].sum() / total), + } + + +# -------------------------------------------------------------------------- +# The stage +# -------------------------------------------------------------------------- + + +@dataclass +class UKNTSBusTravelResult: + frame: Frame + support_clip: UKSupportClipReceipt + donor: Mapping[str, Any] + band: Mapping[str, Any] + incidence: Mapping[str, Any] + band_means: Mapping[str, Any] + trip_rates: Mapping[str, Any] + eligibility: Mapping[str, Any] + vehicle_shares: Mapping[str, Any] + + def evidence(self) -> dict[str, object]: + return { + "stage": UK_NTS_BUS_TRAVEL_STAGE_NAME, + "support_clip": self.support_clip.evidence(), + "donor": dict(self.donor), + "band": dict(self.band), + "incidence": dict(self.incidence), + "band_means": dict(self.band_means), + "trip_rates": dict(self.trip_rates), + "eligibility": dict(self.eligibility), + "vehicle_shares": dict(self.vehicle_shares), + } + + +@dataclass +class UKNTSBusTravelStageTransform: + """Whole-stage callable for the NTS local-bus travel imputation.""" + + stage: SourceStageSpec + engine: object + nts_household_tab_path: str | Path | None = None + nts_individual_tab_path: str | Path | None = None + nts_trip_tab_path: str | Path | None = None + nts_household: pd.DataFrame | None = None + nts_individual: pd.DataFrame | None = None + nts_trip: pd.DataFrame | None = None + last_result: UKNTSBusTravelResult | None = field(default=None, init=False) + last_fit_weight_records: tuple[FitWeightRecord, ...] | None = field( + default=None, init=False + ) + + @property + def fit_weight_records(self) -> tuple[FitWeightRecord, ...]: + if self.last_fit_weight_records is None: + return () + return tuple(self.last_fit_weight_records) + + def _table(self, supplied: pd.DataFrame | None, path: str | Path | None, role: str): + if supplied is not None: + return supplied + if path is None: + raise NTSBusTravelError( + f"{UK_NTS_BUS_TRAVEL_STAGE_NAME} requires the caller-supplied {role} tab." + ) + return read_pinned_tab( + Path(path).expanduser().resolve(), _artifact(self.stage, role) + ) + + def __call__(self, frame: Frame) -> Frame: + assert_rules_engine_country(self.engine, "uk") + derive = _operation(self.stage, CLEAN_NTS_TRAVEL_TABLES_KIND) + columns = NTSColumns.from_parameters(derive) + cars_clip = tuple(int(v) for v in derive.get("cars_clip", (0, 5))) + donor = clean_nts_travel_tables( + self._table( + self.nts_household, + self.nts_household_tab_path, + UK_NTS_HOUSEHOLD_TAB_ROLE, + ), + self._table( + self.nts_individual, + self.nts_individual_tab_path, + UK_NTS_INDIVIDUAL_TAB_ROLE, + ), + self._table(self.nts_trip, self.nts_trip_tab_path, UK_NTS_TRIP_TAB_ROLE), + columns=columns, + cars_clip=(cars_clip[0], cars_clip[1]), + ) + band_parameters = _operation(self.stage, IMPUTE_BUS_USE_BAND_KIND) + income_edges = [float(v) for v in band_parameters["income_band_edges"]] + region_remap = { + str(k): str(v) + for k, v in _mapping( + band_parameters.get("region_remap", {}), "region_remap" + ).items() + } + recipient = recipient_predictors( + frame, + self.engine, + columns=columns, + income_band_edges=income_edges, + region_remap=region_remap, + cars_clip=(cars_clip[0], cars_clip[1]), + ) + seed = int(band_parameters.get("seed", 0)) + household_weights = frame.weights_for("household").values + household_table = frame.table("household") + weight_by_household = dict( + zip(household_table["household_id"], household_weights, strict=True) + ) + person_weights = np.asarray( + [weight_by_household[h] for h in recipient["person_household_id"]], + dtype=float, + ) + if donor.frequency_source == FREQUENCY_SOURCE_INTERVIEW: + imputation = impute_bus_use_band( + donor.person, + recipient, + seed=seed, + n_estimators=int(band_parameters.get("n_estimators", 100)), + ) + means, means_receipt = band_means_from_donor(donor.person) + else: + imputation = draw_band_from_published_shares( + recipient, + stage=self.stage, + household_weights=weight_by_household, + seed=seed, + ) + shares = _band_shares(imputation.band, person_weights) + means, means_receipt = band_means_from_published_rate( + self.stage, band_shares=shares + ) + band = imputation.band + trips = assign_trips_from_band_means( + band, recipient["residence_group"].to_numpy(), means + ) + rules = eligibility_rules( + _operation(self.stage, ASSIGN_BUS_PASS_ELIGIBILITY_KIND) + ) + eligible, eligibility_receipt = assign_bus_pass_eligibility( + recipient["age"].to_numpy(), recipient["residence_region"].to_numpy(), rules + ) + # Donor-side eligible share of trips per series (the fare-paying share + # the pricing step reads beside the publisher's concessionary share). + donor_regions = donor.person["region"].to_numpy().astype(str) + donor_ages = _band_lower_ages( + donor.person["age_band"].to_numpy(), columns.age_band_edges + ) + donor_eligible, _ = assign_bus_pass_eligibility( + donor_ages, donor_regions, rules + ) + donor_w = donor.person["weight"].to_numpy(dtype=float) + eligible_trip_share = {} + for series, column in SERIES_TRIP_COLUMNS.items(): + v = donor.person[column].to_numpy(dtype=float) * donor_w + eligible_trip_share[series] = ( + float(v[donor_eligible].sum() / v.sum()) if v.sum() > 0 else None + ) + eligibility_receipt["donor_eligible_trip_share"] = eligible_trip_share + eligibility_receipt["donor_age_basis"] = ( + "band lower bound (the extract carries banded ages)" + ) + # Person-level support clip on the band and the trips. + draws = pd.DataFrame({BAND_COLUMN: band.astype(float), **trips}) + donor_support = pd.DataFrame( + { + BAND_COLUMN: donor.person[BAND_COLUMN].to_numpy(dtype=float) + if BAND_COLUMN in donor.person + else np.arange(len(BAND_IDS), dtype=float), + **{ + column: np.asarray( + [ + v + for group in RESIDENCE_GROUPS + for v in means[series][group].values() + ], + dtype=float, + ) + for series, column in SERIES_TRIP_COLUMNS.items() + }, + } + if BAND_COLUMN not in donor.person + else donor.person[ + [BAND_COLUMN, *SERIES_TRIP_COLUMNS.values(), TRIPS_COLUMN] + ] + ) + if TRIPS_COLUMN not in donor_support: + donor_support[TRIPS_COLUMN] = ( + donor_support[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + + donor_support[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]] + ) + clip = support_clip_to_donor_with_receipt( + draws, + donor_support, + columns=UK_NTS_SUPPORT_CLIP_COLUMNS, + stage=UK_NTS_BUS_TRAVEL_STAGE_NAME, + ) + clipped = clip.clipped + # Outputs. + person = frame.table("person").copy() + person[BAND_COLUMN] = clipped[BAND_COLUMN].to_numpy().astype(np.int64) + for column in ( + SERIES_TRIP_COLUMNS[BUS_IN_LONDON], + SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], + TRIPS_COLUMN, + ): + person[column] = clipped[column].to_numpy(dtype=float) + person[ELIGIBLE_COLUMN] = eligible + household = household_table.copy() + by_household = ( + pd.Series( + person[TRIPS_COLUMN].to_numpy(), + index=person["person_household_id"].to_numpy(), + ) + .groupby(level=0) + .sum() + ) + household[HOUSEHOLD_TRIPS_COLUMN] = ( + by_household.reindex(household["household_id"]) + .fillna(0.0) + .to_numpy(dtype=float) + ) + # Evidence. + recipient_shares = _band_shares(person[BAND_COLUMN].to_numpy(), person_weights) + user_share = 1.0 - recipient_shares[BAND_IDS[NON_USER_BAND]] + older = recipient["age"].to_numpy() >= 60 + older_shares = _band_shares( + person[BAND_COLUMN].to_numpy()[older], person_weights[older] + ) + incidence = { + "frequency_source": donor.frequency_source, + "person_band_shares": recipient_shares, + "person_user_share": user_share, + "aged_60_and_over_band_shares": older_shares, + "aged_60_and_over_user_share": 1.0 - older_shares[BAND_IDS[NON_USER_BAND]], + "household_user_share": float( + np.asarray(household_weights)[ + household["household_id"] + .isin( + person.loc[ + person[BAND_COLUMN] > NON_USER_BAND, "person_household_id" + ] + ) + .to_numpy() + ].sum() + / float(np.asarray(household_weights).sum()) + ), + } + trip_rates = _trip_rate_receipt( + person, recipient, person_weights, band_parameters + ) + vehicle_shares = { + "frame": frame_car_availability( + household_table, + household_weights, + england_regions=[r for r in columns.region_codes.values()], + ), + "published": published_car_availability(band_parameters), + "basis": "design-weighted England households; num_vehicles is the was_wealth draw", + } + result = uk_national_frame( + person=person, + benunit=frame.table("benunit").copy(), + household=household, + time_period=uk_time_period(frame), + weight_kind=uk_household_weight_kind(frame), + household_weights=household_weights, + mass_log=frame.mass_log, + ) + validate_uk_national_frame(result) + self.last_fit_weight_records = imputation.fit_weight_records + self.last_result = UKNTSBusTravelResult( + frame=result, + support_clip=clip.receipt, + donor=donor.receipt, + band=imputation.receipt, + incidence=incidence, + band_means=means_receipt, + trip_rates=trip_rates, + eligibility=eligibility_receipt, + vehicle_shares=vehicle_shares, + ) + return result + + @staticmethod + def output_columns() -> tuple[str, ...]: + return UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS + + def checkpoint_metadata(self) -> dict[str, object]: + if self.last_result is None: + return {} + return {"evidence": self.last_result.evidence()} + + +def _band_lower_ages(age_band: np.ndarray, edges: Sequence[int]) -> np.ndarray: + lower = np.asarray(edges, dtype=float) + return lower[np.clip(np.asarray(age_band, dtype=int), 0, len(lower) - 1)] + + +def _trip_rate_receipt( + person: pd.DataFrame, + recipient: pd.DataFrame, + weights: np.ndarray, + parameters: Mapping[str, Any], +) -> dict[str, Any]: + published = published_trip_rates(parameters) + frame_rates = { + series: float(np.average(person[column].to_numpy(dtype=float), weights=weights)) + for series, column in SERIES_TRIP_COLUMNS.items() + } + by_age: dict[str, dict[str, float]] = {} + ages = recipient["age"].to_numpy(dtype=float) + for label, lower, upper in ( + ("0 to 16", 0, 17), + ("17 to 20", 17, 21), + ("21 to 29", 21, 30), + ("30 to 39", 30, 40), + ("40 to 49", 40, 50), + ("50 to 59", 50, 60), + ("60 to 69", 60, 70), + ("70 and over", 70, 10_000), + ): + mask = (ages >= lower) & (ages < upper) + if weights[mask].sum() > 0: + by_age[label] = { + series: float( + np.average( + person[column].to_numpy(dtype=float)[mask], + weights=weights[mask], + ) + ) + for series, column in SERIES_TRIP_COLUMNS.items() + } + return { + "basis": "design-weighted persons of the frame", + "frame_trips_per_person": frame_rates, + "published_trips_per_person": published, + "published_period_value": int(parameters["trip_rates_period_value"]), + "relative_deviation": { + series: (frame_rates[series] / published[series] - 1.0) + if published[series] + else None + for series in SERIES + }, + "frame_trips_per_person_by_age_band": by_age, + } 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 d8247249a..b2946e6bf 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 @@ -63,6 +63,12 @@ def uk_stage_health_gate( return _household_composition_gate(stage, evidence, parameters) if check == "energy_rake": return _energy_rake_gate(stage, evidence, parameters) + if check == "bus_travel_facts": + return _bus_travel_facts_gate(stage, evidence, parameters) + if check == "bus_pricing": + return _bus_pricing_gate(stage, evidence, parameters) + if check == "fact_rake": + return _fact_rake_gate(stage, evidence, parameters) return GateResult( name="stage_health", passed=False, @@ -1277,3 +1283,340 @@ def _household_composition_gate( if failures: return _fail(stage, check, failures, details) return _pass(stage, check, details) + + +def _bus_travel_facts_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """The NTS bus-travel stage reproduces the published incidence and trip rates. + + Fact checks on the ``nts_bus_travel`` receipts, every published value + recomputed here from the vendored rows the stage declares (never taken + from the receipt): the frame's design-weighted share of persons who use + a local bus at least yearly must sit within ``maximum_user_share_deviation`` + (points) of the vendored NTS0313 all-ages share, and the frame's mean + local-bus trips per person per series within ``maximum_trip_rate_deviation`` + (relative) of the vendored NTS0303 rate of the declared year. The receipt + must name its frequency source; a missing block fails closed. + """ + + from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.nts_bus_travel import ( + BAND_IDS, + NON_USER_BAND, + SERIES, + published_band_shares, + published_trip_rates, + ) + + check = "bus_travel_facts" + incidence = _mapping(evidence.get("incidence"), label=f"{stage}.incidence") + trip_rates = _mapping(evidence.get("trip_rates"), label=f"{stage}.trip_rates") + share_tolerance = _finite_number( + parameters.get("maximum_user_share_deviation"), + label=f"{stage}.maximum_user_share_deviation", + ) + rate_tolerance = _finite_number( + parameters.get("maximum_trip_rate_deviation"), + label=f"{stage}.maximum_trip_rate_deviation", + ) + period_value = parameters.get("trip_rates_period_value") + if not isinstance(period_value, int) or isinstance(period_value, bool): + raise ValueError( + f"{stage}: bus_travel_facts declares no trip_rates_period_value." + ) + spec_stage = load_country_spec("uk").sources.stage_map()[stage] + declared_band = next( + ( + dict(op.parameters) + for op in spec_stage.operations + if op.kind == "impute_bus_use_band" + ), + None, + ) + if declared_band is None: + raise ValueError(f"{stage}: declares no impute_bus_use_band operation.") + if int(declared_band.get("trip_rates_period_value", -1)) != period_value: + raise ValueError( + f"{stage}: the gate's trip_rates_period_value {period_value} differs from " + f"the stage's declared {declared_band.get('trip_rates_period_value')!r}." + ) + failures: list[str] = [] + details: dict[str, object] = { + "trip_rates_period_value": period_value, + "maximum_user_share_deviation": share_tolerance, + "maximum_trip_rate_deviation": rate_tolerance, + "frequency_source": incidence.get("frequency_source"), + } + if incidence.get("frequency_source") not in ("interview_band", "published_shares"): + failures.append(f"{stage}: the incidence receipt names no frequency source.") + all_ages, _older, _receipt = published_band_shares(spec_stage) + published_user = 1.0 - float(all_ages[BAND_IDS[NON_USER_BAND]]) + achieved_user = incidence.get("person_user_share") + if not isinstance(achieved_user, int | float): + failures.append(f"{stage}: the incidence receipt carries no person_user_share.") + else: + details["user_share"] = { + "published": published_user, + "achieved": float(achieved_user), + } + if abs(float(achieved_user) - published_user) > share_tolerance: + failures.append( + f"{stage}: local-bus user share {float(achieved_user):.4f} is not the " + f"published {published_user:.4f} (tolerance {share_tolerance} points)." + ) + published_rates = published_trip_rates(declared_band) + frame_rates = _mapping( + trip_rates.get("frame_trips_per_person"), + label=f"{stage}.frame_trips_per_person", + ) + recorded = _mapping( + trip_rates.get("published_trips_per_person"), + label=f"{stage}.published_trips_per_person", + ) + details["trip_rates"] = {} + for series in SERIES: + published = float(published_rates[series]) + if not isinstance(recorded.get(series), int | float) or abs( + float(recorded[series]) - published + ) > 1e-9 * max(1.0, published): + failures.append( + f"{stage}: the receipt's published {series} rate " + f"{recorded.get(series)!r} is not the vendored {published}." + ) + achieved = frame_rates.get(series) + if not isinstance(achieved, int | float): + failures.append(f"{stage}: the receipt carries no frame {series} rate.") + continue + deviation = float(achieved) / published - 1.0 if published > 0 else None + details["trip_rates"][series] = { + "published": published, + "achieved": float(achieved), + "relative_deviation": deviation, + } + if deviation is None or abs(deviation) > rate_tolerance: + failures.append( + f"{stage}: frame {series} trips per person {float(achieved):.3f} " + f"deviate {deviation!r} from the published {published:.3f}, above " + f"the tolerance {rate_tolerance}." + ) + return ( + _fail(stage, check, failures, details) + if failures + else _pass(stage, check, details) + ) + + +def _bus_pricing_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """The lcfs bus-fare pricing used the published yields and translations. + + Fact checks on the lcfs ``bus_pricing`` receipt, every published value + recomputed here from the vendored rows the stage declares (never taken + from the receipt): for every declared area the receipts, boardings, + concessionary journeys, trips per person and population, and the + boardings-per-trip and yield factors derived from them, must equal the + receipt's to ``maximum_relative_deviation``; the unpriced regions must be + the declared ones; and the receipt must state that the chain conditioned + on the raw draw. The frame-implied boardings against the published ones + are reported, not fenced: that ratio is the survey-versus-admin reading + the calibration targets then act on (microcosm#930). + """ + + from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.bus_fare_pricing import bus_fare_prices + from microcosm.build.uk_runtime.lcfs_consumption import ( + UK_LCFS_VENDORED_RESOURCES, + bus_pricing_operation, + ) + + check = "bus_pricing" + receipt = _mapping(evidence.get("bus_pricing"), label=f"{stage}.bus_pricing") + tolerance = _finite_number( + parameters.get("maximum_relative_deviation"), + label=f"{stage}.maximum_relative_deviation", + ) + declared = bus_pricing_operation(load_country_spec("uk").sources.stage_map()[stage]) + if declared is None: + raise ValueError(f"{stage}: declares no price_bus_journeys operation.") + prices = bus_fare_prices(declared, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + failures: list[str] = [] + details: dict[str, object] = { + "maximum_relative_deviation": tolerance, + "areas_fact_checked": 0, + "frame_implied_over_published_boardings": {}, + } + if receipt.get("chain_conditioned_on") != "raw_draw": + failures.append(f"{stage}: the chain did not condition on the raw draw.") + if sorted(str(r) for r in receipt.get("unpriced_regions", ())) != sorted( + prices.unpriced_regions + ): + failures.append( + f"{stage}: unpriced regions {receipt.get('unpriced_regions')!r} are not " + f"the declared {sorted(prices.unpriced_regions)}." + ) + recorded = _mapping(receipt.get("prices"), label=f"{stage}.bus_pricing.prices") + expected = { + "london_series": prices.london, + **{a.label: a for a in prices.other_by_region.values()}, + } + + def _close(observed: object, value: float) -> bool: + return isinstance(observed, int | float) and abs(float(observed) - value) <= ( + tolerance * max(1.0, abs(value)) + ) + + for label, area in expected.items(): + block = recorded.get(label) + if not isinstance(block, Mapping): + failures.append(f"{stage}: the receipt prices no area {label!r}.") + continue + for key, value in ( + ("boardings_per_trip", area.boardings_per_trip), + ("yield_per_fare_paying_boarding", area.yield_per_fare_paying_boarding), + ("fare_per_trip", area.fare_per_trip), + ("concessionary_boarding_share", area.concessionary_boarding_share), + ): + if not _close(block.get(key), value): + failures.append( + f"{stage}: {label} {key} {block.get(key)!r} is not the vendored " + f"{value}." + ) + for key, value in ( + ("receipts", area.receipts), + ("boardings", area.boardings), + ("concessionary", area.concessionary_boardings), + ("trips_per_person", area.trips_per_person), + ): + inner = block.get(key) + observed = inner.get("value") if isinstance(inner, Mapping) else None + if not _close(observed, value): + failures.append( + f"{stage}: {label} {key} {observed!r} is not the vendored {value}." + ) + population = block.get("population") + observed = population.get("value") if isinstance(population, Mapping) else None + if not _close(observed, area.population): + failures.append( + f"{stage}: {label} population {observed!r} is not the vendored " + f"{area.population}." + ) + details["areas_fact_checked"] = int(details["areas_fact_checked"]) + 1 + by_area = receipt.get("by_area") + if isinstance(by_area, Mapping): + for label, entry in by_area.items(): + if isinstance(entry, Mapping): + details["frame_implied_over_published_boardings"][str(label)] = ( + entry.get("frame_implied_over_published_boardings") + ) + return ( + _fail(stage, check, failures, details) + if failures + else _pass(stage, check, details) + ) + + +def _fact_rake_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """A declared rake to vendored facts hit every published cell it declares. + + Fact checks on a stage's ``rake_to_vendored_facts`` receipt (the ETB + bus-support rake, microcosm#930 C7): every cell's published value is + recomputed from the vendored rows through the stage's own declaration + (never taken from the receipt) and must equal the receipt's; each cell's + design-weighted total after the rake must equal its published value to + ``maximum_relative_deviation`` (a joint cell over the sum of its columns); + a skipped cell fails closed. The receipt key is ``receipt_key`` + (``bus_support_rake`` for the ETB stage). + """ + + from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.fact_raking import rake_operations, resolve_cells + + check = "fact_rake" + key = str(parameters.get("receipt_key") or "") + if not key: + raise ValueError(f"{stage}: fact_rake declares no receipt_key.") + receipt = _mapping(evidence.get(key), label=f"{stage}.{key}") + tolerance = _finite_number( + parameters.get("maximum_relative_deviation"), + label=f"{stage}.maximum_relative_deviation", + ) + allowed = tuple(str(r) for r in parameters.get("allowed_resources", ())) + if not allowed: + raise ValueError(f"{stage}: fact_rake declares no allowed_resources.") + spec_stage = load_country_spec("uk").sources.stage_map()[stage] + operations = rake_operations(spec_stage) + if len(operations) != 1: + raise ValueError( + f"{stage}: fact_rake expects one rake_to_vendored_facts operation, " + f"found {len(operations)}." + ) + cells = { + cell.label: cell + for cell in resolve_cells(operations[0], allowed_resources=allowed) + } + failures: list[str] = [] + details: dict[str, object] = { + "receipt_key": key, + "maximum_relative_deviation": tolerance, + "cells_fact_checked": 0, + "achieved": {}, + } + skipped = receipt.get("skipped_cells") or () + if skipped: + failures.append( + f"{stage}: {len(skipped)} rake cell(s) were skipped: {skipped!r}." + ) + recorded_cells = { + str(c.get("label")): c + for c in receipt.get("cells", ()) + if isinstance(c, Mapping) + } + fits = [f for f in receipt.get("fits", ()) if isinstance(f, Mapping)] + joint_fits = [f for f in receipt.get("joint_fits", ()) if isinstance(f, Mapping)] + for label, cell in cells.items(): + recorded = recorded_cells.get(label) + if recorded is None: + failures.append(f"{stage}: the receipt carries no cell {label!r}.") + continue + value = recorded.get("value") + if not isinstance(value, int | float) or abs(float(value) - cell.value) > ( + 1e-9 * max(1.0, cell.value) + ): + failures.append( + f"{stage}: cell {label!r} was raked to {value!r}, not the vendored " + f"{cell.value}." + ) + if cell.joint_columns: + achieved = sum( + float(sum(dict(f.get("weighted_total_after") or {}).values())) + for f in joint_fits + if str(f.get("label")) == label + ) + else: + achieved = sum( + float(sum(dict(f.get("weighted_total_after") or {}).values())) + for f in fits + if str(f.get("label")) == label + ) + details["achieved"][label] = {"published": cell.value, "achieved": achieved} + details["cells_fact_checked"] = int(details["cells_fact_checked"]) + 1 + if abs(achieved - cell.value) > tolerance * max(1.0, cell.value): + failures.append( + f"{stage}: cell {label!r} totals {achieved:.2f} after the rake against " + f"the published {cell.value:.2f} (tolerance {tolerance})." + ) + return ( + _fail(stage, check, failures, details) + if failures + else _pass(stage, check, details) + ) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py index c4d310eb3..e1db5069b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py @@ -186,6 +186,8 @@ def __post_init__(self) -> None: "household.household_is_capital_gains_clone", "household.household_is_cgt_band_donor", "household.household_is_spi_synthetic", + # #930: the NTS bus-travel stage's household journey cell. + "household.household_local_bus_trips", "household.la_code_oa", # #953: the engine's household local_authority enum input, written by the # rowwise geography ladder from local_authority_code. The incumbent never @@ -211,6 +213,8 @@ def __post_init__(self) -> None: "person.attends_private_school_random_draw", "person.capital_gains_asset_type", "person.capital_gains_residential_property", + "person.bus_in_london_trips", + "person.bus_pass_eligible", "person.care_hours", "person.charitable_investment_gifts", "person.dla_m_category", @@ -225,8 +229,11 @@ def __post_init__(self) -> None: "person.is_parent", "person.is_uc_claimant", "person.legacy_jobseeker_proxy", + "person.local_bus_trips", + "person.local_bus_use_band", "person.ons_family_index", "person.ons_family_role", + "person.other_local_bus_trips", "person.outpatient_visits", "person.pension_contributions_via_salary_sacrifice", "person.pip_dl_category", diff --git a/packages/microcosm-build/tests/test_country_spec.py b/packages/microcosm-build/tests/test_country_spec.py index 8a235a407..487e10c4e 100644 --- a/packages/microcosm-build/tests/test_country_spec.py +++ b/packages/microcosm-build/tests/test_country_spec.py @@ -1000,6 +1000,7 @@ def test_uk_source_manifest_loads_thirty_stages(self) -> None: # 31 spine stages (uc_reporter_redraw #832, uc_deduction_attributes # #685, frs_relationships #791, hmrc_cgt_asset_type_spine #725, then # cgt_incidence_anchor #970 as the newest) plus the two certified-pair + # nts_bus_travel #930 as the newest) plus the two certified-pair # stages the June path still uses. assert len(spec.sources.stages) == 33 @@ -1348,11 +1349,15 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_ledger_compile_parity_local_incumbent_2025", "uk_target_surface_local_default_2025", "uk_stage_was_wealth_support", + "uk_stage_nts_bus_travel_support", + "uk_stage_nts_bus_travel_facts", "uk_stage_uc_deduction_attributes", "uk_stage_lcfs_consumption_support", "uk_stage_lcfs_consumption_energy_rake", + "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", + "uk_stage_etb_services_support_rake", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", @@ -1444,11 +1449,15 @@ def test_strict_absent_evidence_entries_are_declared(self, manifest) -> None: flagged = [g.id for g in manifest.gates if g.evidence_absent_blocks] assert flagged == [ "uk_stage_was_wealth_support", + "uk_stage_nts_bus_travel_support", + "uk_stage_nts_bus_travel_facts", "uk_stage_uc_deduction_attributes", "uk_stage_lcfs_consumption_support", "uk_stage_lcfs_consumption_energy_rake", + "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", + "uk_stage_etb_services_support_rake", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", diff --git a/packages/microcosm-build/tests/test_uk_bus_fare_pricing.py b/packages/microcosm-build/tests/test_uk_bus_fare_pricing.py new file mode 100644 index 000000000..87fcd7c30 --- /dev/null +++ b/packages/microcosm-build/tests/test_uk_bus_fare_pricing.py @@ -0,0 +1,252 @@ +"""Bus fares priced from journeys at the published yield (microcosm#930 C6).""" + +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.uk_runtime.bus_fare_pricing import ( + BUS_IN_LONDON, + OTHER_LOCAL_BUS, + PRICE_BUS_JOURNEYS_KIND, + BusFarePricingError, + bus_fare_prices, + price_bus_journeys, + published_fact, +) +from microcosm.build.uk_runtime.lcfs_consumption import ( + UK_LCFS_VENDORED_RESOURCES, + bus_pricing_operation, +) +from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows + + +def _declared() -> dict: + stage = load_country_spec("uk").sources.stage_map()["lcfs_consumption"] + parameters = bus_pricing_operation(stage) + assert parameters is not None and parameters["kind"] == PRICE_BUS_JOURNEYS_KIND + return parameters + + +def test_prices_recompute_from_the_vendored_rows() -> None: + prices = bus_fare_prices(_declared(), allowed_resources=UK_LCFS_VENDORED_RESOURCES) + london = prices.london + assert london.series == BUS_IN_LONDON and london.regions == () + receipts = float( + vendored_rows( + "dft_bus_value_anchors.json", + concept="dft.local_bus_passenger_fare_receipts", + fiscal_start="2024-04-01", + geography_id="E12000007", + )[0]["value"] + ) + journeys = [ + r + for r in vendored_rows( + "dft_bus_journeys.json", + concept="dft.local_bus_passenger_journeys", + fiscal_start="2024-04-01", + geography_id="E12000007", + ) + ] + total = float(next(r["value"] for r in journeys if not r["dimensions"])) + concessionary = float( + next( + r["value"] + for r in journeys + if r["dimensions"].get("journey_category") == "total_concessionary" + ) + ) + assert london.receipts == pytest.approx(receipts) + assert london.boardings == pytest.approx(total) + assert london.concessionary_boardings == pytest.approx(concessionary) + assert london.yield_per_fare_paying_boarding == pytest.approx( + receipts / (total - concessionary) + ) + trips = float( + vendored_rows( + "dft_bus_value_anchors.json", + concept="dft.bus_in_london_trips_per_person", + period_value=2024, + groupby_value_id="all", + )[0]["value"] + ) + population = sum( + float(r["value"]) + for r in vendored_rows( + "dft_bus_journeys.json", + concept="ons.mid_year_population_estimate", + period_value=2024, + ) + if str(r["geography"]["id"]).startswith("E12") + ) + assert london.trips_per_person == pytest.approx(trips) + assert london.population == pytest.approx(population) + assert london.boardings_per_trip == pytest.approx(total / (trips * population)) + assert london.fare_per_trip == pytest.approx( + london.boardings_per_trip * london.yield_per_fare_paying_boarding + ) + # Order of magnitude: about a pound per fare-paying boarding, two boardings + # per resident trip, a fare per resident trip between one and five pounds. + assert 0.5 < london.yield_per_fare_paying_boarding < 2.0 + assert 1.0 < london.boardings_per_trip < 4.0 + assert 1.0 < london.fare_per_trip < 5.0 + assert set(prices.other_by_region) == { + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + "SCOTLAND", + "NORTHERN_IRELAND", + } + assert prices.unpriced_regions == frozenset({"WALES"}) + scotland = prices.other_by_region["SCOTLAND"] + assert scotland.trips_basis == "england_other_local_bus_rate_as_proxy" + assert scotland.receipts == pytest.approx(391_000_000.0) + ni = prices.other_by_region["NORTHERN_IRELAND"] + assert ni.receipts == pytest.approx(49_584_434.28 + 100_498_383.21, rel=1e-6) + assert ni.concessionary_boardings == pytest.approx(8_960_000.0) + assert "composition check" in prices.receipt["algebra"] + + +def test_published_fact_refuses_the_wrong_resource_unit_or_split() -> None: + selector = { + "resource": "dft_bus_journeys.json", + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + } + value, receipt = published_fact( + selector, + unit="count", + allowed_resources=UK_LCFS_VENDORED_RESOURCES, + fiscal_start="2024-04-01", + ) + assert value > 1e9 and receipt["unit"] == "count" + with pytest.raises(BusFarePricingError, match="not a resource the stage declares"): + published_fact( + {**selector, "resource": "orr_rail_facts.json"}, + unit="count", + allowed_resources=UK_LCFS_VENDORED_RESOURCES, + fiscal_start="2024-04-01", + ) + with pytest.raises(BusFarePricingError, match="expected 'gbp' rows"): + published_fact( + selector, + unit="gbp", + allowed_resources=UK_LCFS_VENDORED_RESOURCES, + fiscal_start="2024-04-01", + ) + with pytest.raises(BusFarePricingError, match="sum_over"): + published_fact( + { + "resource": "devolved_bus_finance.json", + "concept": "dfi_ni.translink_bus.passenger_receipts", + "sum_over": {"service": ["metro_glider", "ulsterbus", "rail"]}, + }, + unit="gbp", + allowed_resources=UK_LCFS_VENDORED_RESOURCES, + fiscal_start="2024-04-01", + ) + + +def test_declaration_refusals() -> None: + declared = _declared() + duplicated = {**declared, "areas": [*declared["areas"], declared["areas"][2]]} + with pytest.raises(BusFarePricingError, match="priced twice"): + bus_fare_prices(duplicated, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + no_london = {**declared, "areas": declared["areas"][1:]} + with pytest.raises(BusFarePricingError, match="bus_in_london"): + bus_fare_prices(no_london, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + + +def test_household_fares_sum_non_eligible_persons_and_keep_wales_raw() -> None: + prices = bus_fare_prices(_declared(), allowed_resources=UK_LCFS_VENDORED_RESOURCES) + household = pd.DataFrame( + { + "household_id": [1, 2, 3, 4], + "region": ["LONDON", "SOUTH_EAST", "WALES", "SCOTLAND"], + } + ) + person = pd.DataFrame( + { + "person_id": [11, 12, 21, 31, 41, 42], + "person_household_id": [1, 1, 2, 3, 4, 4], + "bus_in_london_trips": [100.0, 50.0, 0.0, 0.0, 0.0, 0.0], + "other_local_bus_trips": [0.0, 10.0, 40.0, 30.0, 20.0, 20.0], + "bus_pass_eligible": [False, True, False, False, False, True], + } + ) + weights = np.array([1.0, 2.0, 3.0, 4.0]) + raw = np.array([500.0, 600.0, 700.0, 800.0]) + fares, priced, receipt = price_bus_journeys( + person, + household, + prices=prices, + trips_columns={ + BUS_IN_LONDON: "bus_in_london_trips", + OTHER_LOCAL_BUS: "other_local_bus_trips", + }, + eligibility_column="bus_pass_eligible", + household_weights=weights, + raw_household_fares=raw, + ) + london = prices.london.fare_per_trip + england = prices.other_by_region["SOUTH_EAST"].fare_per_trip + scotland = prices.other_by_region["SCOTLAND"].fare_per_trip + # Household 1: person 11 pays 100 London trips; person 12 is eligible. + assert fares[0] == pytest.approx(100.0 * london) + assert fares[1] == pytest.approx(40.0 * england) + assert fares[2] == 700.0 and not priced[2] + assert fares[3] == pytest.approx(20.0 * scotland) + assert priced.tolist() == [True, True, False, True] + assert receipt["households_unpriced_keep_raw_draw"] == 1 + assert receipt["persons_eligible_zero_priced"] == 2 + assert receipt["unpriced_regions"] == ["WALES"] + area = receipt["by_area"]["london_series"] + assert area["weighted_trips"] == pytest.approx(150.0) + assert area["weighted_eligible_trips"] == pytest.approx(50.0) + assert area["frame_eligible_trip_share"] == pytest.approx(50.0 / 150.0) + assert area["frame_implied_boardings"] == pytest.approx( + 150.0 * prices.london.boardings_per_trip + ) + assert receipt["weighted_fares_before"] == pytest.approx(500 + 2 * 600 + 4 * 800) + assert receipt["weighted_fares_after"] == pytest.approx( + fares[0] + 2 * fares[1] + 4 * fares[3] + ) + with pytest.raises( + BusFarePricingError, match="neither priced nor declared unpriced" + ): + price_bus_journeys( + person, + household.assign(region=["LONDON", "ATLANTIS", "WALES", "SCOTLAND"]), + prices=prices, + trips_columns={ + BUS_IN_LONDON: "bus_in_london_trips", + OTHER_LOCAL_BUS: "other_local_bus_trips", + }, + eligibility_column="bus_pass_eligible", + household_weights=weights, + raw_household_fares=raw, + ) + with pytest.raises( + BusFarePricingError, match="nts_bus_travel stage must run first" + ): + price_bus_journeys( + person.drop(columns=["bus_pass_eligible"]), + household, + prices=prices, + trips_columns={ + BUS_IN_LONDON: "bus_in_london_trips", + OTHER_LOCAL_BUS: "other_local_bus_trips", + }, + eligibility_column="bus_pass_eligible", + household_weights=weights, + raw_household_fares=raw, + ) diff --git a/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py b/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py new file mode 100644 index 000000000..9ae5e8c69 --- /dev/null +++ b/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py @@ -0,0 +1,193 @@ +"""The value-side bus-support diagnostic beside the ETB rake (microcosm#930 C7).""" + +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.uk_runtime.bus_fare_pricing import ( + BusFarePricingError, + published_fact, +) +from microcosm.build.uk_runtime.bus_support_per_journey import ( + RECORD_SUPPORT_PER_JOURNEY_KIND, + support_per_journey_diagnostic, +) +from microcosm.build.uk_runtime.etb_services import ( + UK_ETB_SERVICES_VENDORED_RESOURCES, +) + +ENGLAND_OUTSIDE_LONDON = ( + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST", +) + + +def _declared() -> dict: + stage = load_country_spec("uk").sources.stage_map()["etb_services"] + parameters = next( + dict(op.parameters) + for op in stage.operations + if op.kind == RECORD_SUPPORT_PER_JOURNEY_KIND + ) + assert parameters["support_column"] == "bus_subsidy_spending" + assert [a["label"] for a in parameters["support_areas"]] == [ + "london", + "england_outside_london", + ] + assert parameters["support_areas"][1]["regions"] == list(ENGLAND_OUTSIDE_LONDON) + return parameters + + +def _frame() -> tuple[pd.DataFrame, pd.DataFrame, np.ndarray, np.ndarray]: + household = pd.DataFrame( + { + "household_id": [1, 2, 3, 4], + "region": ["LONDON", "SOUTH_EAST", "NORTH_WEST", "WALES"], + } + ) + person = pd.DataFrame( + { + "person_id": [11, 12, 21, 31, 41], + "person_household_id": [1, 1, 2, 3, 4], + "bus_in_london_trips": [100.0, 40.0, 0.0, 10.0, 0.0], + "other_local_bus_trips": [0.0, 10.0, 60.0, 30.0, 50.0], + "bus_pass_eligible": [False, True, True, False, True], + } + ) + weights = np.array([2.0, 3.0, 4.0, 5.0]) + raked = np.array([120.0, 80.0, 90.0, 70.0]) + return person, household, weights, raked + + +def test_value_side_support_recomputes_from_the_vendored_rows() -> None: + parameters = _declared() + person, household, weights, raked = _frame() + receipt = support_per_journey_diagnostic( + parameters, + person=person, + household=household, + household_weights=weights, + raked_support=raked, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + assert receipt["operation"] == RECORD_SUPPORT_PER_JOURNEY_KIND + assert receipt["applied"] is False + assert receipt["support_column"] == "bus_subsidy_spending" + k_london = receipt["boardings_per_trip"]["bus_in_london"] + k_england = receipt["boardings_per_trip"]["england_outside_london"] + assert k_london > 0 and k_england > 0 + + area = dict(parameters["support_areas"][1]) + fiscal_start = parameters["fiscal_start"] + reimbursement, _ = published_fact( + area["reimbursement"], + unit="gbp", + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + fiscal_start=fiscal_start, + ) + net_support, _ = published_fact( + area["net_support"], + unit="gbp", + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + fiscal_start=fiscal_start, + ) + boardings, _ = published_fact( + area["boardings"], + unit="count", + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + fiscal_start=fiscal_start, + ) + concessionary, _ = published_fact( + area["concessionary"], + unit="count", + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + fiscal_start=fiscal_start, + ) + assert 0 < reimbursement < net_support + assert 0 < concessionary < boardings + england = receipt["by_area"]["england_outside_london"] + # Households 2 (SOUTH_EAST, weight 3) and 3 (NORTH_WEST, weight 4): + # person 21 (eligible) 60 other trips; person 31 10 London + 30 other trips. + all_boardings = 3.0 * 60.0 * k_england + 4.0 * (10.0 * k_london + 30.0 * k_england) + eligible_boardings = 3.0 * 60.0 * k_england + assert england["frame_boardings"] == pytest.approx(all_boardings) + assert england["frame_eligible_boardings"] == pytest.approx(eligible_boardings) + assert england["frame_eligible_boarding_share"] == pytest.approx( + eligible_boardings / all_boardings + ) + assert england["published_concessionary_boarding_share"] == pytest.approx( + concessionary / boardings + ) + assert england["reimbursement_per_concessionary_boarding"] == pytest.approx( + reimbursement / concessionary + ) + assert england["other_support_per_boarding"] == pytest.approx( + (net_support - reimbursement) / boardings + ) + assert england["value_side_support"] == pytest.approx( + reimbursement / concessionary * eligible_boardings + + (net_support - reimbursement) / boardings * all_boardings + ) + assert england["raked_support"] == pytest.approx(3.0 * 80.0 + 4.0 * 90.0) + assert england["value_side_over_raked"] == pytest.approx( + england["value_side_support"] / england["raked_support"] + ) + assert england["households"] == 2 and england["persons"] == 2 + london = receipt["by_area"]["london"] + assert london["frame_boardings"] == pytest.approx( + 2.0 * (100.0 * k_london + 40.0 * k_london + 10.0 * k_england) + ) + # Person 12 is eligible: 40 London-series and 10 other-local-bus trips. + assert london["frame_eligible_boardings"] == pytest.approx( + 2.0 * (40.0 * k_london + 10.0 * k_england) + ) + assert london["raked_support"] == pytest.approx(2.0 * 120.0) + # Wales is unpriced and outside every support area: recorded nowhere. + assert set(receipt["by_area"]) == {"london", "england_outside_london"} + + +def test_diagnostic_refusals() -> None: + parameters = _declared() + person, household, weights, raked = _frame() + with pytest.raises( + BusFarePricingError, match="nts_bus_travel stage must run first" + ): + support_per_journey_diagnostic( + parameters, + person=person.drop(columns=["bus_pass_eligible"]), + household=household, + household_weights=weights, + raked_support=raked, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + foreign = dict(parameters) + foreign["support_areas"] = [ + {**dict(parameters["support_areas"][0]), "regions": ["LONDON", "WALES"]} + ] + with pytest.raises(BusFarePricingError, match="pricing areas do not price"): + support_per_journey_diagnostic( + foreign, + person=person, + household=household, + household_weights=weights, + raked_support=raked, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + with pytest.raises(BusFarePricingError, match="not a record_support_per_journey"): + support_per_journey_diagnostic( + {**parameters, "kind": "price_bus_journeys"}, + person=person, + household=household, + household_weights=weights, + raked_support=raked, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) diff --git a/packages/microcosm-build/tests/test_uk_bus_use_incidence.py b/packages/microcosm-build/tests/test_uk_bus_use_incidence.py index a859e1a96..0ded9e696 100644 --- a/packages/microcosm-build/tests/test_uk_bus_use_incidence.py +++ b/packages/microcosm-build/tests/test_uk_bus_use_incidence.py @@ -10,19 +10,32 @@ from microcosm.build.uk_runtime.bus_use_incidence import ( BusUseBandShares, assign_bus_use_incidence, - incidence_operation, nts_band_shares, under_threshold_shares, ) -from microcosm.build.uk_runtime.lcfs_consumption import lcfs_bus_use_incidence from microcosm.build.uk_runtime.national_frame import uk_national_frame def _declared() -> dict: - stage = load_country_spec("uk").sources.stage_map()["lcfs_consumption"] - parameters = incidence_operation(stage) - assert parameters is not None - return parameters + """The published-shares draw as the nts_bus_travel stage declares it. + + The #890 lcfs declaration (`assign_bus_use_incidence`) retired with + microcosm#930; the same block lives on as the stage's fallback for an + extract without the frequency column, and NTS0313 stays fact-checked + through it. + """ + + stage = load_country_spec("uk").sources.stage_map()["nts_bus_travel"] + fallback = next( + ( + dict(op.parameters["fallback"]) + for op in stage.operations + if op.kind == "impute_bus_use_band" + ), + None, + ) + assert fallback is not None + return fallback def test_declared_bands_read_both_nts_series_by_label() -> None: @@ -49,7 +62,7 @@ def test_declared_bands_read_both_nts_series_by_label() -> None: assert receipt["user_definition"] == "at_least_once_a_year" assert receipt["share_geography"] == "E92000001" assert receipt["share_age_coverage"] == "all_ages" - assert receipt["applied_to"] == "fare_rake_regions" + assert receipt["applied_to"] == "every_person" @pytest.mark.parametrize( @@ -66,7 +79,7 @@ def test_declared_bands_read_both_nts_series_by_label() -> None: (lambda p: p.update(period_value=1999), "missing an NTS series"), (lambda p: p.update(user_definition="ever"), "user_definition"), (lambda p: p.pop("share_geography"), "declares no share_geography"), - (lambda p: p.update(applied_to="everywhere"), "fare_rake_regions only"), + (lambda p: p.update(applied_to="everywhere"), "every_person"), ], ) def test_declaration_refusals(mutation, match: str) -> None: @@ -154,7 +167,15 @@ def test_household_incidence_is_identity_keyed_and_rolls_up_any_user() -> None: assert again.household_user.tolist() == first.household_user.tolist() -def test_stage_helper_draws_from_the_declaration_on_a_frame() -> None: +def test_nts_fallback_declaration_draws_from_the_published_shares() -> None: + """The nts_bus_travel fallback block is the #890 draw, declared once more. + + With no interview frequency column in the extract the stage draws each + person's band from the vendored NTS0313/NTS0621 shares through this + declaration (``applied_to: every_person``); the lcfs stage no longer + carries an incidence draw (#930). + """ + frame = uk_national_frame( person=pd.DataFrame( { @@ -170,19 +191,26 @@ def test_stage_helper_draws_from_the_declaration_on_a_frame() -> None: ), time_period="2024", ) - stage = load_country_spec("uk").sources.stage_map()["lcfs_consumption"] - - result = lcfs_bus_use_incidence(stage, frame) - - assert result is not None + stage = load_country_spec("uk").sources.stage_map()["nts_bus_travel"] + fallback = next( + dict(op.parameters["fallback"]) + for op in stage.operations + if op.kind == "impute_bus_use_band" + ) + assert fallback["applied_to"] == "every_person" + shares, receipt = nts_band_shares(fallback) + result = assign_bus_use_incidence( + frame.table("person"), + frame.table("household"), + household_weights=frame.weights_for("household").values, + shares=shares, + seed=0, + ) assert len(result.household_user) == 3 - assert result.receipt["nts"]["period_value"] == 2024 + assert receipt["period_value"] == 2024 assert result.receipt["older_population_share"] == pytest.approx(3.0 / 7.0) assert set(result.receipt["under_threshold_shares"]) == set( - result.receipt["nts"]["all_ages_shares"] + receipt["all_ages_shares"] ) - - class Stage: - operations = () - - assert lcfs_bus_use_incidence(Stage(), frame) is None + lcfs = load_country_spec("uk").sources.stage_map()["lcfs_consumption"] + assert not any(op.kind == "assign_bus_use_incidence" for op in lcfs.operations) diff --git a/packages/microcosm-build/tests/test_uk_fact_raking.py b/packages/microcosm-build/tests/test_uk_fact_raking.py index baba80807..4a5894d1a 100644 --- a/packages/microcosm-build/tests/test_uk_fact_raking.py +++ b/packages/microcosm-build/tests/test_uk_fact_raking.py @@ -18,7 +18,6 @@ rake_to_facts, resolve_cells, ) -from microcosm.build.uk_runtime.lcfs_consumption import UK_LCFS_VENDORED_RESOURCES from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows OUTSIDE_LONDON = ( @@ -43,63 +42,6 @@ def _fact(resource: str, **criteria) -> float: return float(sum(row["value"] for row in rows)) -def test_lcfs_fare_cells_resolve_to_the_fy2024_25_published_receipts() -> None: - (operation,) = rake_operations(_stage("lcfs_consumption")) - assert operation["columns"] == ["bus_fare_spending"] - assert operation["scope"] == "users_only" - assert operation["quintile_income"] == "hbai_household_net_income" - - cells = { - cell.label: cell - for cell in resolve_cells( - operation, allowed_resources=UK_LCFS_VENDORED_RESOURCES - ) - } - assert set(cells) == { - "london", - "england_outside_london", - "scotland", - "northern_ireland", - } - assert cells["london"].regions == ("LONDON",) - assert cells["england_outside_london"].regions == OUTSIDE_LONDON - assert cells["london"].value == _fact( - "dft_bus_value_anchors.json", - concept="dft.local_bus_passenger_fare_receipts", - fiscal_start="2024-04-01", - geography_id="E12000007", - ) - assert cells["england_outside_london"].value == _fact( - "dft_bus_value_anchors.json", - concept="dft.local_bus_passenger_fare_receipts", - fiscal_start="2024-04-01", - geography_id="dft:england_outside_london", - ) - assert cells["scotland"].value == 391_000_000.0 - assert cells["northern_ireland"].value == pytest.approx( - 49_584_434.28 + 100_498_383.21 - ) - assert cells["london"].allocation == "income_quintile_trips" - assert set(cells["london"].quintile_trips) == { - "lowest", - "second", - "third", - "fourth", - "highest", - } - assert ( - cells["london"].quintile_trips["lowest"] - > cells["london"].quintile_trips["third"] - ) - assert cells["scotland"].allocation == "uniform" - assert cells["scotland"].quintile_trips is None - receipt = cells["northern_ireland"].receipt - assert receipt["selector"]["sum_over"] == {"service": ["ulsterbus", "metro_glider"]} - assert len(receipt["source_record_ids"]) == 2 - # Wales publishes no fare receipts: no cell names it. - assert not any("WALES" in cell.regions for cell in cells.values()) - - def test_etb_support_cells_cover_every_nation_with_the_ni_joint_cell() -> None: (operation,) = rake_operations(_stage("etb_services")) assert operation["columns"] == ["bus_subsidy_spending"] @@ -139,7 +81,7 @@ def test_etb_support_cells_cover_every_nation_with_the_ni_joint_cell() -> None: def test_resolve_cells_refuses_resources_the_stage_does_not_declare() -> None: - (operation,) = rake_operations(_stage("lcfs_consumption")) + (operation,) = rake_operations(_stage("etb_services")) with pytest.raises(ValueError, match="does not declare"): resolve_cells(operation, allowed_resources=("road_fuel_anchors.json",)) import copy @@ -147,11 +89,13 @@ def test_resolve_cells_refuses_resources_the_stage_does_not_declare() -> None: duplicated = copy.deepcopy(operation) duplicated["cells"][1]["regions"].append("LONDON") with pytest.raises(ValueError, match="repeats regions"): - resolve_cells(duplicated, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + resolve_cells(duplicated, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES) wrong_period = copy.deepcopy(operation) wrong_period["cells"][0]["selector"]["fiscal_start"] = "1999-04-01" with pytest.raises(ValueError, match="expected exactly one row"): - resolve_cells(wrong_period, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + resolve_cells( + wrong_period, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + ) def test_person_income_quintiles_rank_people_not_households() -> None: diff --git a/packages/microcosm-build/tests/test_uk_frs_spine.py b/packages/microcosm-build/tests/test_uk_frs_spine.py index a81aa1afc..267f19373 100644 --- a/packages/microcosm-build/tests/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/test_uk_frs_spine.py @@ -2063,18 +2063,30 @@ def test_input_artifact_pins_bind_spi_donor_and_ods() -> None: "etb_household_tab", "lcfs_household_tab", "lcfs_person_tab", + "nts_household_tab", + "nts_individual_tab", + "nts_trip_tab", "published_fact_surface", "qrf_donor", "was_qrf_donor", } - for pin in pins.values(): + # The NTS tabs (#930) are declared with placeholder pins until the licensed + # extract lands: a zero size and an all-zero digest the runtime refuses. + # Flip this to the positive branch when the tabs are pinned. + pending = {"nts_household_tab", "nts_individual_tab", "nts_trip_tab"} + for role, pin in pins.items(): assert len(str(pin["sha256"])) == 64 - assert int(pin["size_bytes"]) > 0 assert str(pin["filename"]) + if role in pending: + assert int(pin["size_bytes"]) == 0 + assert str(pin["sha256"]) == "0" * 64 + else: + assert int(pin["size_bytes"]) > 0 declared = { str(artifact["role"]): str(artifact["sha256"]) for stage_name in ( "was_wealth", + "nts_bus_travel", "lcfs_consumption", "etb_vat", "etb_services", @@ -2100,9 +2112,9 @@ def test_e8_manifest_seeds_all_reach_the_build_sidecar_harvester() -> None: ) assert declared["cgt_incidence_clone"] == {"cgt_prior_amount": 0} + assert declared["nts_bus_travel"] == {"local_bus_use_band": 0} assert declared["lcfs_consumption"] == { "has_fuel_consumption": 0, - "uses_local_bus": 0, "lcfs_consumption": 0, } assert declared["uc_capital_coherence"] == {"frs_benunit_capital": 0} diff --git a/packages/microcosm-build/tests/test_uk_graph.py b/packages/microcosm-build/tests/test_uk_graph.py index a7faa91ec..f6e04fc3d 100644 --- a/packages/microcosm-build/tests/test_uk_graph.py +++ b/packages/microcosm-build/tests/test_uk_graph.py @@ -167,6 +167,9 @@ def test_uk_spine_graph_contains_manifest_stages_and_named_exclusions() -> None: # #791 frs_relationships, #725 hmrc_cgt_asset_type_spine and #970 # cgt_incidence_anchor stages; the two named exclusions are the # certified-pair alternatives, not steps of this pipeline. + # #791 frs_relationships, #725 hmrc_cgt_asset_type_spine and #930 + # nts_bus_travel stages; the two named exclusions are the certified-pair + # alternatives, not steps of this pipeline. assert len(expected) == 31 assert UK_SPINE_EXCLUSIONS == { "frs_hmrc_retained_leaves", @@ -227,6 +230,9 @@ def test_uk_production_graph_binds_split_donor_sources_and_runtime_config() -> N assert {source.name for source in graph.sources} == { "frs", "was", + "nts_household", + "nts_individual", + "nts_trip", "lcfs_household", "lcfs_person", "etb", @@ -303,6 +309,7 @@ def test_uk_adapter_source_changes_invalidate_all_consuming_stages(monkeypatch): "frs_education_grant_split", "frs_brma", "was_wealth", + "nts_bus_travel", "lcfs_consumption", "etb_vat", "etb_services", diff --git a/packages/microcosm-build/tests/test_uk_lcfs_consumption.py b/packages/microcosm-build/tests/test_uk_lcfs_consumption.py index c942f48e9..6dfa59eac 100644 --- a/packages/microcosm-build/tests/test_uk_lcfs_consumption.py +++ b/packages/microcosm-build/tests/test_uk_lcfs_consumption.py @@ -591,12 +591,12 @@ def _synthetic_lcfs_donor( return person, pd.DataFrame(household) -def test_stage_transform_imposes_bus_incidence_and_rakes_fares_to_the_facts() -> None: +def test_stage_transform_prices_bus_fares_from_journeys() -> None: """End to end on synthetic inputs: the committed declaration minus the engine. The uprating step needs the installed engine and is dropped; the QRF is shrunk to four trees. Everything else is the committed lcfs_consumption - stage (#890 A, E2, I and D). + stage (#890 A, E2; #930 pricing). """ import dataclasses @@ -608,7 +608,6 @@ def test_stage_transform_imposes_bus_incidence_and_rakes_fares_to_the_facts() -> UK_LCFS_CONSUMPTION_ENGINE_PREDICTORS, UK_LCFS_CONSUMPTION_OUTPUT_COLUMNS, ) - from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows committed = load_country_spec("uk").sources.stage_map()["lcfs_consumption"] operations = [] @@ -643,12 +642,22 @@ def test_stage_transform_imposes_bus_incidence_and_rakes_fares_to_the_facts() -> "household_gross_income": rng.uniform(5e3, 9e4, n), } ) + ages = rng.integers(1, 90, 2 * n).astype(float) person = pd.DataFrame( { "person_id": np.arange(1, 2 * n + 1), "person_benunit_id": np.repeat(np.arange(1, n + 1), 2), "person_household_id": np.repeat(np.arange(1, n + 1), 2), - "age": rng.integers(1, 90, 2 * n).astype(float), + "age": ages, + # The nts_bus_travel stage's cells: journeys per series and the + # statutory concessionary eligibility (here, 66 and over). + "bus_in_london_trips": np.where( + np.repeat(regions, 2) == "LONDON", rng.uniform(0, 200, 2 * n), 0.0 + ), + "other_local_bus_trips": np.where( + np.repeat(regions, 2) == "LONDON", 0.0, rng.uniform(0, 120, 2 * n) + ), + "bus_pass_eligible": ages >= 66, } ) frame = uk_national_frame( @@ -706,8 +715,7 @@ def materialize(self, frame, variables, period): assert { "support_clip", "has_fuel_consumption", - "bus_use_incidence", - "bus_fare_rake", + "bus_pricing", "energy_pricing", "energy_rake", } <= set(evidence) @@ -727,51 +735,53 @@ def materialize(self, frame, variables, period): no_vehicle = household["num_vehicles"].to_numpy() == 0 assert (out.loc[no_vehicle, "petrol_spending"] == 0.0).all() assert 0.95 < evidence["has_fuel_consumption"]["ice_share"]["rate"] < 0.97 - # Bus: non-user households are zero, user cells hit the published totals. - incidence = evidence["bus_use_incidence"] - assert incidence["users_filled_from_positive_regime"] >= 0 - assert ( - incidence["users_in_scope"] - == incidence["users_drawn_positive"] - + (incidence["users_filled_from_positive_regime"]) - ) - assert 0.3 < incidence["household_user_share"] < 0.95 - rake = evidence["bus_fare_rake"] - assert rake["scope"] == "users_only" - fares = out["bus_fare_spending"].to_numpy() - weights = result.weights_for("household").values - london_total = float( - np.dot(fares[regions == "LONDON"], weights[regions == "LONDON"]) - ) - published_london = float( - vendored_rows( - "dft_bus_value_anchors.json", - concept="dft.local_bus_passenger_fare_receipts", - fiscal_start="2024-04-01", - geography_id="E12000007", - )[0]["value"] - ) - assert london_total == pytest.approx(published_london) - ni = regions == "NORTHERN_IRELAND" - assert float(np.dot(fares[ni], weights[ni])) == pytest.approx( - 49_584_434.28 + 100_498_383.21 - ) + # Bus: fares are journeys times the published yield in every priced region; + # Wales keeps the chain's raw draw, clipped to donor support. + pricing = evidence["bus_pricing"] + assert pricing["chain_conditioned_on"] == "raw_draw" + assert pricing["unpriced_regions"] == ["WALES"] wales = regions == "WALES" - # The incidence override is imposed only where a fare cell levels the - # amounts; Wales (no published receipts) keeps the chain's raw draw, so - # its positive share is the QRF's, not the NTS user share. - assert incidence["households_outside_scope_keep_raw_draw"] == int(wales.sum()) - assert incidence["users_in_scope"] == int((fares[~wales] > 0).sum()) - donor_max = donor_household[list(BUS_FARE_LCFS_CODES)].sum(axis=1).max() * ( - 365.25 / 7 - ) - assert fares[wales].max() <= donor_max + 1e-6 - assert {fit["label"] for fit in rake["fits"]} == { - "london", + assert pricing["households_priced"] == int((~wales).sum()) + assert set(pricing["by_area"]) == { + "london_series", "england_outside_london", "scotland", "northern_ireland", } + fares = out["bus_fare_spending"].to_numpy() + prices = pricing["prices"] + fare_per_trip = { + "LONDON": prices["england_outside_london"]["fare_per_trip"], + "SOUTH_EAST": prices["england_outside_london"]["fare_per_trip"], + "NORTH_WEST": prices["england_outside_london"]["fare_per_trip"], + "SCOTLAND": prices["scotland"]["fare_per_trip"], + "NORTHERN_IRELAND": prices["northern_ireland"]["fare_per_trip"], + } + london_fare = prices["london_series"]["fare_per_trip"] + expected = np.zeros(n) + for row in person.itertuples(index=False): + h = int(row.person_household_id) - 1 + region = regions[h] + if region == "WALES" or row.bus_pass_eligible: + continue + expected[h] += row.bus_in_london_trips * london_fare + expected[h] += row.other_local_bus_trips * fare_per_trip[region] + assert np.allclose(fares[~wales], expected[~wales]) + donor_max = donor_household[list(BUS_FARE_LCFS_CODES)].sum(axis=1).max() * ( + 365.25 / 7 + ) + assert fares[wales].max() <= donor_max + 1e-6 + # Every published factor is on the receipt beside its source records. + london = prices["london_series"] + assert london["yield_per_fare_paying_boarding"] == pytest.approx( + london["receipts"]["value"] + / (london["boardings"]["value"] - london["concessionary"]["value"]) + ) + assert london["boardings_per_trip"] == pytest.approx( + london["boardings"]["value"] + / (london["trips_per_person"]["value"] * london["population"]["value"]) + ) + assert pricing["by_area"]["london_series"]["frame_implied_boardings"] > 0 def test_fuel_litres_audit_reads_the_vendored_prices_litres_and_obr_split() -> None: diff --git a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py new file mode 100644 index 000000000..31bf74c5d --- /dev/null +++ b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py @@ -0,0 +1,481 @@ +"""The NTS bus-travel stage (microcosm#930): cleaning, band draw, trips, eligibility.""" + +from __future__ import annotations + +import dataclasses +from types import SimpleNamespace + +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 SourceOperationSpec +from microcosm.build.uk_runtime.national_frame import uk_national_frame +from microcosm.build.uk_runtime.nts_bus_travel import ( + BAND_IDS, + BUS_IN_LONDON, + IMPUTE_BUS_USE_BAND_KIND, + LONDON_GROUP, + MAX_BAND, + NON_USER_BAND, + OTHER_LOCAL_BUS, + REST_OF_ENGLAND_GROUP, + SERIES_TRIP_COLUMNS, + UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS, + WEEKS_IN_YEAR, + NTSBusTravelError, + NTSColumns, + UKNTSBusTravelStageTransform, + assign_bus_pass_eligibility, + assign_trips_from_band_means, + band_means_from_donor, + clean_nts_travel_tables, + eligibility_rules, + impute_bus_use_band, + published_band_shares, + published_car_availability, + published_trip_rates, + recipient_predictors, +) +from microcosm.build.uk_runtime.stage_health import uk_stage_health_gate + + +def _committed_stage(): + return load_country_spec("uk").sources.stage_map()["nts_bus_travel"] + + +def _operation(stage, kind: str) -> dict: + return next(dict(op.parameters) for op in stage.operations if op.kind == kind) + + +def _columns() -> NTSColumns: + return NTSColumns.from_parameters( + _operation(_committed_stage(), "clean_nts_travel_tables") + ) + + +def _synthetic_nts( + households: int = 90, *, frequency: bool = True +) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: + rows = np.arange(households) + household = pd.DataFrame( + { + "HouseholdID": 1000 + rows, + "SurveyYear": 2022 + rows % 3, + "HHoldGOR_B02ID": 1 + rows % 9, + "HHIncome2002_B02ID": 1 + rows % 3, + "NumCarVan": rows % 4, + "HHoldNumPeople": 1 + rows % 3, + "W2": 1.0 + (rows % 5) / 10.0, + } + ) + persons = [] + for household_id, size in zip( + household["HouseholdID"], household["HHoldNumPeople"], strict=True + ): + for member in range(int(size)): + index = int(household_id) * 10 + member + row = { + "IndividualID": index, + "HouseholdID": int(household_id), + "Age_B01ID": 1 + index % 10, + "Sex_B01ID": 1 + index % 2, + } + if frequency: + row["LocalBusFreq_B01ID"] = 1 + index % 7 + persons.append(row) + individual = pd.DataFrame(persons) + trips = [] + trip_id = 1 + for _, person in individual.iterrows(): + band_code = int(person.get("LocalBusFreq_B01ID", 7)) + count = max(0, 7 - band_code) + london = (int(person["HouseholdID"]) - 1000) % 9 == 6 + for t in range(count): + trips.append( + { + "TripID": trip_id, + "IndividualID": int(person["IndividualID"]), + "HouseholdID": int(person["HouseholdID"]), + "MainMode_B04ID": 7 if london else 8, + "W5xHH": 1.0 + (t % 3) / 10.0, + "JJXSC": 1.0, + } + ) + trip_id += 1 + trips.append( + { + "TripID": trip_id, + "IndividualID": int(person["IndividualID"]), + "HouseholdID": int(person["HouseholdID"]), + "MainMode_B04ID": 3, + "W5xHH": 1.0, + "JJXSC": 1.0, + } + ) + trip_id += 1 + return household, individual, pd.DataFrame(trips) + + +def test_declared_columns_and_codes_parse_from_the_committed_stage() -> None: + columns = _columns() + assert columns.london_region_code == 7 + assert set(columns.region_codes.values()) == { + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "LONDON", + "SOUTH_EAST", + "SOUTH_WEST", + } + assert columns.mode_codes == {BUS_IN_LONDON: 7, OTHER_LOCAL_BUS: 8} + assert columns.frequency_codes[1] == MAX_BAND and columns.frequency_codes[7] == 0 + assert columns.survey_years == (2022, 2023, 2024) + bad = dict(_operation(_committed_stage(), "clean_nts_travel_tables")) + bad["codes"] = {**bad["codes"], "main_mode": {"bus_in_london": 7}} + with pytest.raises(NTSBusTravelError, match="main_mode"): + NTSColumns.from_parameters(bad) + + +def test_cleaning_annualises_diary_trips_per_series_and_maps_the_codebook() -> None: + household, individual, trip = _synthetic_nts() + donor = clean_nts_travel_tables(household, individual, trip, columns=_columns()) + person = donor.person + assert donor.frequency_source == "interview_band" + assert len(person) == len(individual) + assert set(person["region"]) <= set(_columns().region_codes.values()) + assert set(person["income_band"]) == {1, 2, 3} + assert person["num_vehicles"].between(0, 5).all() + # Frequency code 1 (3+ a week) is the top band; code 7 the non-user band. + codes = individual.set_index("IndividualID")["LocalBusFreq_B01ID"] + expected = person["individual_id"].map(codes).map(lambda c: 7 - int(c)) + assert (person["local_bus_use_band"].to_numpy() == expected.to_numpy()).all() + # Trips: 52.14 x sum(W5xHH x JJXSC) over the bus trips only. + bus = trip[trip["MainMode_B04ID"].isin([7, 8])] + per_person = (bus["W5xHH"] * bus["JJXSC"]).groupby(bus["IndividualID"]).sum() + expected_trips = person["individual_id"].map(per_person).fillna(0.0) * WEEKS_IN_YEAR + assert np.allclose(person["local_bus_trips"], expected_trips) + london = person["residence_group"] == LONDON_GROUP + assert (person.loc[london, "other_local_bus_trips"] == 0).all() + assert (person.loc[~london, "bus_in_london_trips"] == 0).all() + assert donor.receipt["persons"] == len(person) + assert donor.receipt["annualisation_weeks"] == WEEKS_IN_YEAR + # A tab whose declared column is absent is refused with the codebook hint. + with pytest.raises(NTSBusTravelError, match="derive.columns"): + clean_nts_travel_tables( + household.drop(columns=["NumCarVan"]), individual, trip, columns=_columns() + ) + + +def test_cleaning_falls_back_to_published_shares_without_a_frequency_column() -> None: + household, individual, trip = _synthetic_nts(frequency=False) + donor = clean_nts_travel_tables(household, individual, trip, columns=_columns()) + assert donor.frequency_source == "published_shares" + assert "local_bus_use_band" not in donor.person + assert donor.receipt["frequency_column"] == "localbusfreq_b01id" + + +def _recipient_frame(n: int = 240, *, seed: int = 3): + rng = np.random.default_rng(seed) + regions = np.array( + ["LONDON", "SOUTH_EAST", "NORTH_WEST", "SCOTLAND", "WALES", "NORTHERN_IRELAND"] + )[np.arange(n) % 6] + household = pd.DataFrame( + { + "household_id": np.arange(1, n + 1), + "household_weight": rng.uniform(0.5, 3.0, n), + "region": regions, + "num_vehicles": np.arange(n) % 3, + } + ) + person = pd.DataFrame( + { + "person_id": np.arange(1, 2 * n + 1), + "person_benunit_id": np.repeat(np.arange(1, n + 1), 2), + "person_household_id": np.repeat(np.arange(1, n + 1), 2), + "age": rng.integers(1, 90, 2 * n).astype(float), + "gender": np.array(["MALE", "FEMALE"])[np.arange(2 * n) % 2], + } + ) + frame = uk_national_frame( + person=person, + benunit=pd.DataFrame({"benunit_id": np.arange(1, n + 1)}), + household=household, + time_period="2024", + ) + return frame, rng + + +class _Engine: + country = "uk" + + def __init__(self, rng: np.random.Generator) -> None: + self.rng = rng + + def variable_metadata(self, name): + return SimpleNamespace(entity="household") + + def materialize(self, frame, variables, period): + rows = len(frame.table("household")) + values = {"household_gross_income": self.rng.uniform(5e3, 9e4, rows)} + return {name: values[name] for name in variables} + + +def test_band_draw_is_identity_keyed_rounded_and_within_the_donor_range() -> None: + household, individual, trip = _synthetic_nts() + columns = _columns() + donor = clean_nts_travel_tables(household, individual, trip, columns=columns) + frame, rng = _recipient_frame() + band_parameters = _operation(_committed_stage(), IMPUTE_BUS_USE_BAND_KIND) + recipient = recipient_predictors( + frame, + _Engine(rng), + columns=columns, + income_band_edges=band_parameters["income_band_edges"], + region_remap=band_parameters["region_remap"], + ) + assert set(recipient["region"]) <= set(columns.region_codes.values()) + assert set(recipient["income_band"]) <= {1, 2, 3} + first = impute_bus_use_band(donor.person, recipient, seed=0, n_estimators=4) + assert first.band.dtype == np.int64 + assert first.band.min() >= NON_USER_BAND and first.band.max() <= MAX_BAND + assert first.receipt["regime"] == "zero_inflated_positive" + assert len(first.fit_weight_records) == 1 + # Permuting the recipients moves nothing: the uniforms are keyed by person id. + order = rng.permutation(len(recipient)) + second = impute_bus_use_band( + donor.person, + recipient.iloc[order].reset_index(drop=True), + seed=0, + n_estimators=4, + ) + assert (second.band == first.band[order]).all() + + +def test_band_means_and_trip_assignment_split_the_series_by_residence_group() -> None: + household, individual, trip = _synthetic_nts() + donor = clean_nts_travel_tables(household, individual, trip, columns=_columns()) + means, receipt = band_means_from_donor(donor.person) + assert set(means) == {BUS_IN_LONDON, OTHER_LOCAL_BUS} + assert set(means[BUS_IN_LONDON]) == {LONDON_GROUP, REST_OF_ENGLAND_GROUP} + # Londoners' non-user band carries no trips; their top band carries some. + assert means[BUS_IN_LONDON][LONDON_GROUP][NON_USER_BAND] == 0.0 + assert means[BUS_IN_LONDON][LONDON_GROUP][MAX_BAND] > 0.0 + assert means[OTHER_LOCAL_BUS][LONDON_GROUP][MAX_BAND] == 0.0 + assert receipt["source"] == "donor_diary_band_means" + band = np.array([0, MAX_BAND, 3, MAX_BAND]) + groups = np.array( + [LONDON_GROUP, LONDON_GROUP, REST_OF_ENGLAND_GROUP, REST_OF_ENGLAND_GROUP] + ) + trips = assign_trips_from_band_means(band, groups, means) + assert trips[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]][0] == 0.0 + assert ( + trips[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]][1] + == means[BUS_IN_LONDON][LONDON_GROUP][MAX_BAND] + ) + assert ( + trips[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]][3] + == means[OTHER_LOCAL_BUS][REST_OF_ENGLAND_GROUP][MAX_BAND] + ) + assert np.allclose( + trips["local_bus_trips"], + trips[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + + trips[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]], + ) + + +def test_eligibility_follows_the_declared_statutory_rules() -> None: + rules = eligibility_rules( + _operation(_committed_stage(), "assign_bus_pass_eligibility") + ) + assert set(rules) == { + "england_outside_london", + "london", + "scotland", + "wales", + "northern_ireland", + } + ages = np.array([10.0, 17.0, 18.0, 21.0, 22.0, 59.0, 60.0, 65.0, 66.0]) + for region, expected in ( + ("SOUTH_EAST", [False, False, False, False, False, False, False, False, True]), + ("LONDON", [True, True, False, False, False, False, True, True, True]), + ("SCOTLAND", [True, True, True, True, False, False, True, True, True]), + ("WALES", [False, False, False, False, False, False, True, True, True]), + ( + "NORTHERN_IRELAND", + [False, False, False, False, False, False, False, True, True], + ), + ): + eligible, receipt = assign_bus_pass_eligibility( + ages, np.array([region] * len(ages)), rules + ) + assert eligible.tolist() == expected, region + assert receipt["eligible_persons"] == sum(expected) + with pytest.raises(NTSBusTravelError, match="no eligibility rule covers"): + assign_bus_pass_eligibility(ages[:1], np.array(["ATLANTIS"]), rules) + + +def test_published_facts_read_the_vendored_rows() -> None: + parameters = _operation(_committed_stage(), IMPUTE_BUS_USE_BAND_KIND) + rates = published_trip_rates(parameters) + assert 5.0 < rates[BUS_IN_LONDON] < 25.0 + assert 15.0 < rates[OTHER_LOCAL_BUS] < 45.0 + cars = published_car_availability(parameters) + assert set(cars) == {"no_car", "one_car", "two_plus_cars"} + assert abs(sum(cars.values()) - 1.0) < 0.02 + all_ages, older, receipt = published_band_shares(_committed_stage()) + assert set(all_ages) == set(BAND_IDS) == set(older) + assert abs(sum(all_ages.values()) - 1.0) < 0.005 + assert 0.4 < 1.0 - all_ages[BAND_IDS[NON_USER_BAND]] < 0.6 + with pytest.raises(NTSBusTravelError, match="trip_rates_resource"): + published_trip_rates( + {**parameters, "trip_rates_resource": "orr_rail_facts.json"} + ) + + +def test_stage_transform_end_to_end_on_synthetic_inputs() -> None: + committed = _committed_stage() + operations = tuple( + SourceOperationSpec( + kind=op.kind, parameters={**op.parameters, "n_estimators": 4} + ) + if op.kind == IMPUTE_BUS_USE_BAND_KIND + else op + for op in committed.operations + ) + stage = dataclasses.replace(committed, operations=operations) + household, individual, trip = _synthetic_nts() + frame, rng = _recipient_frame() + transform = UKNTSBusTravelStageTransform( + stage=stage, + engine=_Engine(rng), + nts_household=household, + nts_individual=individual, + nts_trip=trip, + ) + result = transform(frame) + person = result.table("person") + out_household = result.table("household") + assert set(UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS) <= set(person.columns) | set( + out_household.columns + ) + assert person["local_bus_use_band"].between(NON_USER_BAND, MAX_BAND).all() + assert (person["local_bus_trips"] >= 0).all() + assert ( + person.loc[person["local_bus_use_band"] == NON_USER_BAND, "local_bus_trips"] + == 0 + ).all() + summed = person.groupby("person_household_id")["local_bus_trips"].sum() + assert np.allclose( + out_household["household_local_bus_trips"].to_numpy(), + summed.reindex(out_household["household_id"]).fillna(0.0).to_numpy(), + ) + # Eligibility follows the area rule on the frame's ages. + london = ( + person["person_household_id"].map( + out_household.set_index("household_id")["region"] + ) + == "LONDON" + ) + region = person["person_household_id"].map( + out_household.set_index("household_id")["region"] + ) + assert (person.loc[london & (person["age"] < 18), "bus_pass_eligible"]).all() + # Outside London and Scotland no under-60 is eligible (England's rule is + # State Pension age, Wales 60, Northern Ireland 65); Scotland's under-22s are. + plain = region.isin(["SOUTH_EAST", "NORTH_WEST", "WALES", "NORTHERN_IRELAND"]) + assert (~person.loc[plain & (person["age"] < 60), "bus_pass_eligible"]).all() + assert ( + person.loc[(region == "SCOTLAND") & (person["age"] < 22), "bus_pass_eligible"] + ).all() + evidence = transform.checkpoint_metadata()["evidence"] + assert { + "support_clip", + "donor", + "band", + "incidence", + "band_means", + "trip_rates", + "eligibility", + "vehicle_shares", + } <= set(evidence) + assert evidence["incidence"]["frequency_source"] == "interview_band" + assert 0.0 < evidence["incidence"]["person_user_share"] < 1.0 + assert evidence["trip_rates"]["published_period_value"] == 2024 + assert set(evidence["vehicle_shares"]["published"]) == { + "no_car", + "one_car", + "two_plus_cars", + } + assert ( + evidence["eligibility"]["donor_eligible_trip_share"][OTHER_LOCAL_BUS] + is not None + ) + clip = evidence["support_clip"]["columns"] + assert clip["local_bus_use_band"]["clipped_high_rows"] == 0 + assert clip["local_bus_trips"]["clipped_low_rows"] == 0 + assert len(transform.fit_weight_records) == 1 + + +def test_bus_travel_facts_gate_recomputes_the_published_values() -> None: + stage = _committed_stage() + parameters = { + "stage": "nts_bus_travel", + "check": "bus_travel_facts", + "trip_rates_period_value": 2024, + "maximum_user_share_deviation": 0.05, + "maximum_trip_rate_deviation": 0.15, + } + all_ages, _, _ = published_band_shares(stage) + rates = published_trip_rates(_operation(stage, IMPUTE_BUS_USE_BAND_KIND)) + user = 1.0 - all_ages[BAND_IDS[NON_USER_BAND]] + evidence = { + "stage": "nts_bus_travel", + "incidence": { + "frequency_source": "interview_band", + "person_user_share": user + 0.01, + }, + "trip_rates": { + "frame_trips_per_person": {k: v * 1.05 for k, v in rates.items()}, + "published_trips_per_person": dict(rates), + }, + } + passed = uk_stage_health_gate( + evidence=evidence, + stage="nts_bus_travel", + check="bus_travel_facts", + parameters=parameters, + ) + assert passed.passed, passed.failures + assert passed.details["user_share"]["published"] == pytest.approx(user) + failing = { + "stage": "nts_bus_travel", + "incidence": { + "frequency_source": "interview_band", + "person_user_share": user + 0.2, + }, + "trip_rates": { + "frame_trips_per_person": {k: v * 1.5 for k, v in rates.items()}, + "published_trips_per_person": {k: v * 2 for k, v in rates.items()}, + }, + } + failed = uk_stage_health_gate( + evidence=failing, + stage="nts_bus_travel", + check="bus_travel_facts", + parameters=parameters, + ) + assert not failed.passed + text = " ".join(failed.failures) + assert "user share" in text and "not the vendored" in text and "above" in text + with pytest.raises(ValueError, match="trip_rates_period_value"): + uk_stage_health_gate( + evidence=evidence, + stage="nts_bus_travel", + check="bus_travel_facts", + parameters={**parameters, "trip_rates_period_value": 2023}, + ) diff --git a/packages/microcosm-build/tests/test_uk_release_input_coverage.py b/packages/microcosm-build/tests/test_uk_release_input_coverage.py index 22c5b9cc1..208076022 100644 --- a/packages/microcosm-build/tests/test_uk_release_input_coverage.py +++ b/packages/microcosm-build/tests/test_uk_release_input_coverage.py @@ -625,6 +625,7 @@ def test_shipped_manifest_is_current(self) -> None: "student_loans", "was_wealth", "regional_property_uprating", + "nts_bus_travel", "lcfs_consumption", "etb_vat", "etb_services", diff --git a/packages/microcosm-build/tests/test_uk_source_stages.py b/packages/microcosm-build/tests/test_uk_source_stages.py index 6e81575c8..ab5184a20 100644 --- a/packages/microcosm-build/tests/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/test_uk_source_stages.py @@ -44,6 +44,7 @@ "regional_property_uprating", ] E6_STAGE_NAMES = [ + "nts_bus_travel", "lcfs_consumption", "etb_vat", "etb_services", @@ -311,6 +312,7 @@ def test_country_stage_plan_assembles_spine_plan(self) -> None: "frs_household_draws": _identity, "frs_brma": _identity, "was_wealth": _identity, + "nts_bus_travel": _identity, "regional_property_uprating": _identity, "lcfs_consumption": _identity, "etb_vat": _identity, @@ -638,18 +640,25 @@ def test_e3_operation_kinds_are_declared_in_order(self) -> None: "uprate_to_regional_reference", "record_mass_conservation_receipt", ] + assert [op.kind for op in stages["nts_bus_travel"].operations] == [ + "clean_nts_travel_tables", + "materialize_rules_engine_predictors", + "impute_bus_use_band", + "assign_trips_from_band_means", + "assign_bus_pass_eligibility", + "support_clip", + ] assert [op.kind for op in stages["lcfs_consumption"].operations] == [ "derive", "uprate_donor_columns", "iterative_proportional_fit", "assign_binary_from_rate", - "assign_bus_use_incidence", "materialize_rules_engine_predictors", "fit_weighted_qrf_chain", "support_clip", "iterative_proportional_fit", "price_domestic_energy", - "rake_to_vendored_facts", + "price_bus_journeys", "fold_into", "zero_when_false", "record_mass_conservation_receipt", @@ -668,6 +677,7 @@ def test_e3_operation_kinds_are_declared_in_order(self) -> None: "fit_weighted_qrf_chain", "support_clip", "rake_to_vendored_facts", + "record_support_per_journey", "compute_ratio", "allocate_per_capita_from_cell_table", "record_mass_conservation_receipt", @@ -937,7 +947,6 @@ def test_e6_declared_seed_lockstep(self) -> None: } assert lcfs_seeded == { "assign_binary_from_rate": 0, - "assign_bus_use_incidence": 0, "fit_weighted_qrf_chain": 0, } assert stages["etb_vat"].operations[2].parameters["seed"] == 0 diff --git a/packages/microcosm-build/tests/test_uk_stage_health.py b/packages/microcosm-build/tests/test_uk_stage_health.py index 77120a409..02596a764 100644 --- a/packages/microcosm-build/tests/test_uk_stage_health.py +++ b/packages/microcosm-build/tests/test_uk_stage_health.py @@ -819,3 +819,226 @@ def fails(match: str, **overrides: object) -> None: ) with pytest.raises(ValueError, match="pair_count"): _anchor_gate(_anchor_evidence(pair_count=1.5)) +def _gate_parameters(gate_id: str) -> dict: + import json + from pathlib import Path + + gates = json.loads( + ( + Path(__file__).resolve().parents[1] / "src/microcosm/build/uk/gates.json" + ).read_text("utf-8") + ) + entry = next(g for g in gates["gates"] if g["id"] == gate_id) + assert entry["gate"] == "stage_health" + assert entry["population_fact_check"] is True + assert entry["evidence_absent_blocks"] is True + return dict(entry["parameters"]) + + +def test_bus_pricing_gate_recomputes_every_price_from_the_vendored_rows() -> None: + """The lcfs bus_pricing receipt is fact-checked at stage time (microcosm#930 C6).""" + + import copy + + import pandas as pd + + from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.bus_fare_pricing import ( + BUS_IN_LONDON, + OTHER_LOCAL_BUS, + bus_fare_prices, + price_bus_journeys, + ) + from microcosm.build.uk_runtime.lcfs_consumption import ( + UK_LCFS_VENDORED_RESOURCES, + bus_pricing_operation, + ) + + parameters = _gate_parameters("uk_stage_lcfs_consumption_bus_pricing") + assert parameters["check"] == "bus_pricing" + declared = bus_pricing_operation( + load_country_spec("uk").sources.stage_map()["lcfs_consumption"] + ) + prices = bus_fare_prices(declared, allowed_resources=UK_LCFS_VENDORED_RESOURCES) + household = pd.DataFrame( + { + "household_id": [1, 2, 3, 4, 5], + "region": ["LONDON", "SOUTH_EAST", "WALES", "SCOTLAND", "NORTHERN_IRELAND"], + } + ) + person = pd.DataFrame( + { + "person_id": [11, 12, 21, 31, 41, 51], + "person_household_id": [1, 1, 2, 3, 4, 5], + "bus_in_london_trips": [100.0, 50.0, 0.0, 0.0, 0.0, 0.0], + "other_local_bus_trips": [0.0, 10.0, 40.0, 30.0, 20.0, 25.0], + "bus_pass_eligible": [False, True, False, False, False, True], + } + ) + _, _, receipt = price_bus_journeys( + person, + household, + prices=prices, + trips_columns={ + BUS_IN_LONDON: "bus_in_london_trips", + OTHER_LOCAL_BUS: "other_local_bus_trips", + }, + eligibility_column="bus_pass_eligible", + household_weights=np.array([1.0, 2.0, 3.0, 4.0, 5.0]), + raw_household_fares=np.array([500.0, 600.0, 700.0, 800.0, 900.0]), + ) + receipt = {"chain_conditioned_on": "raw_draw", **prices.receipt, **receipt} + + def run(ev): + return uk_stage_health_gate( + evidence={"stage": "lcfs_consumption", "bus_pricing": ev}, + stage="lcfs_consumption", + check="bus_pricing", + parameters=parameters, + ) + + passed = run(receipt) + assert passed.passed, passed.failures + assert passed.details["areas_fact_checked"] == 1 + len( + {a.label for a in prices.other_by_region.values()} + ) + assert set(passed.details["frame_implied_over_published_boardings"]) >= { + "london_series", + "england_outside_london", + } + tampered = copy.deepcopy(receipt) + tampered["prices"]["london_series"]["yield_per_fare_paying_boarding"] *= 1.01 + result = run(tampered) + assert not result.passed and any( + "yield_per_fare_paying_boarding" in f for f in result.failures + ), result.failures + tampered = copy.deepcopy(receipt) + tampered["prices"]["england_outside_london"]["boardings"]["value"] *= 1.01 + result = run(tampered) + assert not result.passed and any( + "boardings" in f and "not the vendored" in f for f in result.failures + ), result.failures + tampered = copy.deepcopy(receipt) + tampered["chain_conditioned_on"] = "priced" + result = run(tampered) + assert not result.passed and any("raw draw" in f for f in result.failures) + tampered = copy.deepcopy(receipt) + tampered["unpriced_regions"] = ["WALES", "SCOTLAND"] + result = run(tampered) + assert not result.passed and any("unpriced regions" in f for f in result.failures) + with pytest.raises(ValueError, match="bus_pricing must be an object"): + run(None) + + +def test_fact_rake_gate_fact_checks_the_etb_support_rake_receipt() -> None: + """The ETB bus-support rake receipt is fenced at stage time (microcosm#930 C7).""" + + import copy + + import pandas as pd + + from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.etb_services import ( + UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + from microcosm.build.uk_runtime.fact_raking import ( + rake_operations, + rake_to_facts, + resolve_cells, + ) + + parameters = _gate_parameters("uk_stage_etb_services_support_rake") + assert parameters["check"] == "fact_rake" + assert parameters["receipt_key"] == "bus_support_rake" + assert set(parameters["allowed_resources"]) == set( + UK_ETB_SERVICES_VENDORED_RESOURCES + ) + stage = load_country_spec("uk").sources.stage_map()["etb_services"] + (declaration,) = rake_operations(stage) + cells = resolve_cells( + declaration, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + ) + regions = [ + "LONDON", + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST", + "SCOTLAND", + "WALES", + "NORTHERN_IRELAND", + ] + draws = pd.DataFrame( + { + "bus_subsidy_spending": np.linspace(100.0, 320.0, len(regions)), + "rail_subsidy_spending": np.linspace(50.0, 160.0, len(regions)), + } + ) + _, receipt = rake_to_facts( + draws, + columns=["bus_subsidy_spending"], + cells=cells, + region=regions, + weights=np.linspace(1000.0, 12000.0, len(regions)), + scope=str(declaration["scope"]), + iterations=int(declaration.get("iterations", 1)), + ) + assert receipt["skipped_cells"] == [] + + def run(ev, params=parameters): + return uk_stage_health_gate( + evidence={"stage": "etb_services", "bus_support_rake": ev}, + stage="etb_services", + check="fact_rake", + parameters=params, + ) + + passed = run(receipt) + assert passed.passed, passed.failures + assert passed.details["cells_fact_checked"] == len(cells) == 5 + assert set(passed.details["achieved"]) == { + "london", + "england_outside_london", + "scotland", + "wales", + "northern_ireland", + } + for label, block in passed.details["achieved"].items(): + assert block["achieved"] == pytest.approx(block["published"], rel=1e-9), label + tampered = copy.deepcopy(receipt) + tampered["cells"][0]["value"] *= 1.01 + result = run(tampered) + assert not result.passed and any("not the vendored" in f for f in result.failures) + tampered = copy.deepcopy(receipt) + for fit in tampered["fits"]: + if fit["label"] == "scotland": + fit["weighted_total_after"]["bus_subsidy_spending"] *= 1.01 + result = run(tampered) + assert not result.passed and any( + "'scotland' totals" in f for f in result.failures + ), result.failures + tampered = copy.deepcopy(receipt) + for fit in tampered["joint_fits"]: + fit["weighted_total_after"]["rail_subsidy_spending"] *= 1.01 + result = run(tampered) + assert not result.passed and any( + "'northern_ireland' totals" in f for f in result.failures + ), result.failures + tampered = copy.deepcopy(receipt) + tampered["skipped_cells"] = [{"cell": "wales", "reason": "no households"}] + result = run(tampered) + assert not result.passed and any("were skipped" in f for f in result.failures) + tampered = copy.deepcopy(receipt) + tampered["cells"] = [c for c in tampered["cells"] if c["label"] != "wales"] + result = run(tampered) + assert not result.passed and any( + "carries no cell 'wales'" in f for f in result.failures + ) + with pytest.raises(ValueError, match="declares no receipt_key"): + run(receipt, {**parameters, "receipt_key": ""}) + with pytest.raises(ValueError, match="bus_support_rake must be an object"): + run(None) diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index c0b644c0e..f34360418 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -467,11 +467,15 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "preflight", ), "uk_stage_was_wealth_support": ("stage_health", "transferred"), + "uk_stage_nts_bus_travel_support": ("stage_health", "transferred"), + "uk_stage_nts_bus_travel_facts": ("stage_health", "transferred"), "uk_stage_uc_deduction_attributes": ("stage_health", "transferred"), "uk_stage_lcfs_consumption_support": ("stage_health", "transferred"), "uk_stage_lcfs_consumption_energy_rake": ("stage_health", "transferred"), + "uk_stage_lcfs_consumption_bus_pricing": ("stage_health", "transferred"), "uk_stage_etb_vat_support": ("stage_health", "transferred"), "uk_stage_etb_services_support": ("stage_health", "transferred"), + "uk_stage_etb_services_support_rake": ("stage_health", "transferred"), "uk_stage_frs_hmrc_spine_leaves_signal": ( "stage_health", "transferred", @@ -561,11 +565,15 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_degenerate_release_surface", "uk_input_mass_parity", "uk_stage_was_wealth_support", + "uk_stage_nts_bus_travel_support", + "uk_stage_nts_bus_travel_facts", "uk_stage_uc_deduction_attributes", "uk_stage_lcfs_consumption_support", "uk_stage_lcfs_consumption_energy_rake", + "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", + "uk_stage_etb_services_support_rake", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", @@ -721,14 +729,18 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_stage_cgt_incidence_anchor_composition", "uk_stage_cgt_incidence_clone_mass", "uk_stage_etb_services_support", + "uk_stage_etb_services_support_rake", "uk_stage_etb_vat_support", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_frs_relationships_composition", "uk_stage_hmrc_cgt_asset_type_spine_summary", "uk_stage_hmrc_cgt_gains_spine_summary", "uk_stage_hmrc_spi_income_spine_identity", + "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_lcfs_consumption_energy_rake", "uk_stage_lcfs_consumption_support", + "uk_stage_nts_bus_travel_facts", + "uk_stage_nts_bus_travel_support", "uk_stage_salary_sacrifice_realization", "uk_stage_spi_support_channel_mass", "uk_stage_student_loans_realization", @@ -795,6 +807,11 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: ), "policy_sha256": ( "77eace424e352172496f8fd99dbf68f858514198f87f6c6a6b33353d7eff55ad" + "a7250c519e79e22d366316cd4943f5f4bd2cc86a0e76b919ee2ff2eacb2335f3" + "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" + ), + "policy_sha256": ( + "af670e88c0c56c18c7a5b72cfbc2a8669b214e9dfb677f00cc2464d491aa186c" ), }, } diff --git a/packages/microcosm-data/tests/test_contract.py b/packages/microcosm-data/tests/test_contract.py index 9daf01574..98c237504 100644 --- a/packages/microcosm-data/tests/test_contract.py +++ b/packages/microcosm-data/tests/test_contract.py @@ -156,8 +156,12 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: ), "uk_stage_lcfs_consumption_support": ("stage_health", "transferred", None), "uk_stage_lcfs_consumption_energy_rake": ("stage_health", "transferred", None), + "uk_stage_lcfs_consumption_bus_pricing": ("stage_health", "transferred", None), + "uk_stage_nts_bus_travel_support": ("stage_health", "transferred", None), + "uk_stage_nts_bus_travel_facts": ("stage_health", "transferred", None), "uk_stage_etb_vat_support": ("stage_health", "transferred", None), "uk_stage_etb_services_support": ("stage_health", "transferred", None), + "uk_stage_etb_services_support_rake": ("stage_health", "transferred", None), "uk_stage_frs_hmrc_spine_leaves_signal": ( "stage_health", "transferred", @@ -1178,8 +1182,12 @@ def _gate_battery_payload( "uk_stage_uc_deduction_attributes": "uc_deduction_attributes", "uk_stage_lcfs_consumption_support": "lcfs_consumption", "uk_stage_lcfs_consumption_energy_rake": "lcfs_consumption", + "uk_stage_lcfs_consumption_bus_pricing": "lcfs_consumption", + "uk_stage_nts_bus_travel_support": "nts_bus_travel", + "uk_stage_nts_bus_travel_facts": "nts_bus_travel", "uk_stage_etb_vat_support": "etb_vat", "uk_stage_etb_services_support": "etb_services", + "uk_stage_etb_services_support_rake": "etb_services", "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", 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 94a95b485..a9017600f 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 @@ -22,6 +22,9 @@ "hmrc_income_targets": "hmrc_income_targets.json", "lcfs_household": "lcfs_household.csv", "lcfs_person": "lcfs_person.csv", + "nts_household": "nts_household.csv", + "nts_individual": "nts_individual.csv", + "nts_trip": "nts_trip.csv", "spi_donor": "spi_donor.csv", "was": "was.csv" }, @@ -336,6 +339,12 @@ "kind": "public_aggregate_reference", "resource": "devolved_bus_finance.json", "role": "devolved_bus_finance" + }, + { + "format": "json", + "kind": "public_aggregate_reference", + "resource": "dft_bus_journeys.json", + "role": "dft_bus_journeys" } ], "grain": "household+person", @@ -536,6 +545,176 @@ "scope": "all", "weighted": true }, + { + "basis": "value-side alternative recorded beside the raked column, never applied (microcosm#930, Mar\u00eda's ruling pending); England only, where DfT publishes the reimbursement and net support by area", + "eligibility_column": "bus_pass_eligible", + "fiscal_start": "2024-04-01", + "kind": "record_support_per_journey", + "population_period_value": 2024, + "population_resource": "dft_bus_journeys.json", + "pricing_areas": [ + { + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, + "label": "london", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "receipts": { + "concept": "dft.local_bus_passenger_fare_receipts", + "geography_id": "E12000007", + "resource": "dft_bus_value_anchors.json" + }, + "series": "bus_in_london", + "trips_basis": "published_series_rate", + "trips_concept": "dft.bus_in_london_trips_per_person" + }, + { + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, + "label": "england_outside_london", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "receipts": { + "concept": "dft.local_bus_passenger_fare_receipts", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_value_anchors.json" + }, + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST", + "LONDON" + ], + "series": "other_local_bus", + "trips_basis": "published_series_rate", + "trips_concept": "dft.other_local_bus_trips_per_person" + } + ], + "support_areas": [ + { + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, + "label": "london", + "net_support": { + "concept": "dft.local_bus_total_estimated_net_support", + "geography_id": "E12000007", + "resource": "dft_bus_value_anchors.json" + }, + "regions": [ + "LONDON" + ], + "reimbursement": { + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + } + }, + { + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, + "label": "england_outside_london", + "net_support": { + "concept": "dft.local_bus_total_estimated_net_support", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_value_anchors.json" + }, + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST" + ], + "reimbursement": { + "concept": "dft.local_bus_concessionary_travel_reimbursement", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + } + } + ], + "support_column": "bus_subsidy_spending", + "trip_rates_period_value": 2024, + "trip_rates_resource": "dft_bus_value_anchors.json", + "trips_columns": { + "bus_in_london": "bus_in_london_trips", + "other_local_bus": "other_local_bus_trips" + }, + "unpriced_regions": [ + "SCOTLAND", + "WALES", + "NORTHERN_IRELAND" + ] + }, { "denominator_key": "rail_fare_index_2024", "denominator_resource": "etb_services_anchors.json", @@ -2962,8 +3141,8 @@ { "format": "json", "kind": "public_aggregate_reference", - "resource": "nts_bus_use_frequency.json", - "role": "nts_bus_use_frequency" + "resource": "dft_bus_journeys.json", + "role": "dft_bus_journeys" }, { "format": "json", @@ -3000,7 +3179,7 @@ "gas_consumption", "has_fuel_consumption" ], - "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the fare rake (Mar\u00eda's ruling 2026-09-15), which bounds the regions no fare cell levels (Wales keeps the chain's raw draw) while the rake is free to move the raked regions beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Who uses local buses is drawn take-up style (microcosm#890 I), where each person takes a frequency band by an identity-keyed draw from the vendored NTS0313 shares (NTS0621 for people aged 60 and over, the under-60 shares derived from the two with the frame's design-weighted 60-plus share), a household is a user when any member rides at least once a year, user households the chain drew at zero take the bus step's positive-regime draw at an identity-keyed quantile and non-users take zero, in the regions a fare-rake cell levels afterwards (a positive-regime amount is a diary-positive fortnight annualised and would overstate an unraked region several-fold, so Wales keeps the raw draw); the NTS shares are England's and DfT publishes no Scottish or Northern Irish frequency table, so the same shares govern the Scotland and Northern Ireland cells, as declared (share_geography). Bus fares are then raked (microcosm#890 D) so that user households' design-weighted totals equal the FY2024-25 DfT BUS05ai receipts for London and England outside London, spread across design-weighted person income quintiles in proportion to NTS0705a trips per person, Scottish Transport Statistics passenger revenue for Scotland and Translink passenger receipts for Northern Ireland; Wales publishes no fare receipts and is untouched. The 2023-24 diary is uprated to the FRS 2024-25 base year by the declared uprate_donor_columns step (microcosm#890), with consumption columns and bus fares uprated by the engine's CPI index (the fare factor survives only where no fare cell levels the column, i.e. Wales), income predictors by the engine's earnings, mixed-income and pension indices, petrol and diesel by the DESNZ pump-price times HMRC litres per head outturn from the vendored road_fuel_anchors.json; the energy columns are exempt because the NEED 2024 shape at the DESNZ level and the QEP average prices paid set their level.", + "notes": "Ports the incumbent LCFS consumption QRF, including NEED energy raking, with adjudicated weighted fits and an identity-keyed seed-0 fuel flag. The vehicle count is a numeric QRF predictor on both sides (LCFS a124 on the donor, the was_wealth draw of WAS vcarnr8 on the recipient, both clipped to 0-5), which retires the incumbent's WAS-to-LCFS has-fuel bridge (microcosm#890 A). The recipient fuel flag is num_vehicles > 0 times a draw at the fuel-buyer share from the vendored DfT VEH1103 licensed-car stock (one minus the battery-electric and fuel-cell share, 2024, Great Britain; plug-in hybrids count as fuel buyers), replacing the hand-copied NTS share (microcosm#890 E2). Energy support clipping is exempt because NEED raking governs those columns. Bus fares are clipped to donor support before the pricing step (Mar\u00eda's rulings 2026-09-15 and 2026-09-17), which bounds the region no area prices (Wales keeps the chain's raw draw) while the priced regions move beyond donor support afterwards; for that reason the column carries no committed support bound for the terminal gate. Domestic energy is raked in kWh to the NEED 2024 shape at the DESNZ level and priced at the average prices paid (microcosm#890 F, chronicle#270), where both NEED rakes take their mean-kWh margins from the vendored NEED 2024 tables (England and Wales by income band, tenure, property type and region; Scotland by income band, tenure and property type with the all-dwellings mean as its region margin; Northern Ireland untouched), the declared price_domestic_energy step converts spend to kWh and back at each household's QEP price region through the committed crosswalk using the FY2024-25 average variable unit cost and fixed cost across payment methods, standard metering, including VAT (Northern Ireland gas at the UK average because QEP publishes no Northern Ireland gas row), a gas fixed cost only for connected households, the gas connection imposed on the recipient frame at the published share of each region (DESNZ subnational gas meters over electricity meters, 2024) by disconnecting the households with the smallest drawn gas first, skipping a household whose weight would overshoot the published share (Northern Ireland has no subnational row and keeps the positive-gas rule), and after the four-margin NEED rake one factor per fuel scales the kWh so the design-weighted frame total equals the DESNZ Energy Trends domestic consumption at actual temperature summed over the four FY2024-25 quarters; NEED gas means are per gas-metered household, so the gas kWh margins are raked over connected households only while electricity is raked over every household, and the energy_rake gate recomputes every NEED mean, the DESNZ level and the connection shares from the vendored rows. Bus fares are priced from journeys (microcosm#930), where the nts_bus_travel stage imputes each person's annual bus-in-London and other-local-bus trips and their concessionary eligibility, and the declared price_bus_journeys step sets bus_fare_spending as the sum over the household's non-eligible persons of trips times boardings per resident trip (the published BUS01 journeys over the published NTS0705a trips per resident times the ONS population) times the yield per fare-paying boarding (BUS05ai receipts over journeys less concessionary journeys), per area; bus-in-London trips take the London area's price for every resident, other-local-bus trips the price of the residence area (England outside London; Scotland and Northern Ireland from their own receipts and journeys with England's trip rate as the declared proxy); Wales is unpriced and keeps the raw draw. The chain still draws bus_fare_spending so later targets condition on the same raw draw; the emitted column is the priced value. The receipt records every factor, the frame-implied boardings beside the published ones and the frame's eligible trip share beside the publisher's concessionary boarding share, so the design-weight fit of the bound receipts targets is read as a composition check, never a level the stage set; the", "operations": [ { "annualization_weeks": 52.17857142857143, @@ -3150,74 +3329,6 @@ "fuel_cell_electric" ] }, - { - "age_threshold": 60, - "applied_to": "fare_rake_regions", - "bands": [ - { - "id": "three_or_more_times_a_week", - "labels": [ - "3 or more times a week (%)" - ], - "trips_per_year": 208 - }, - { - "id": "once_or_twice_a_week", - "labels": [ - "Once or twice a week (%)" - ], - "trips_per_year": 78 - }, - { - "id": "less_than_weekly_more_than_twice_a_month", - "labels": [ - "Less than once a week, more than once or twice a month (%)", - "Less than once per week, more than twice a month (%)" - ], - "trips_per_year": 36 - }, - { - "id": "once_or_twice_a_month", - "labels": [ - "Once or twice a month (%)" - ], - "trips_per_year": 18 - }, - { - "id": "less_than_monthly_more_than_twice_a_year", - "labels": [ - "Less than once a month, more than once or twice a year (%)", - "Less than once a month, more than twice a year (%)" - ], - "trips_per_year": 6 - }, - { - "id": "once_or_twice_a_year", - "labels": [ - "Once or twice a year (%)" - ], - "trips_per_year": 1.5 - }, - { - "id": "less_than_once_a_year_or_never", - "labels": [ - "Less than once a year or never (%)" - ], - "trips_per_year": 0 - } - ], - "kind": "assign_bus_use_incidence", - "non_user_band": "less_than_once_a_year_or_never", - "older_age_band": "60 and over", - "output": "uses_local_bus", - "period_value": 2024, - "resource": "nts_bus_use_frequency.json", - "seed": 0, - "share_age_coverage": "all_ages", - "share_geography": "E92000001", - "transport_mode_groupby_value_id": "local_bus", - "user_definition": "at_least_once_a_year" - }, { "kind": "materialize_rules_engine_predictors", "predictors": [ @@ -3326,29 +3437,73 @@ "vat_treatment": "including_vat" }, { - "cells": [ + "areas": [ { - "allocation": "income_quintile_trips", - "allocation_concept": "dft.bus_in_london_trips_per_person", - "allocation_period_value": 2024, - "allocation_resource": "dft_bus_value_anchors.json", + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "E12000007", + "resource": "dft_bus_journeys.json" + }, "label": "london", - "regions": [ - "LONDON" + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" ], - "resource": "dft_bus_value_anchors.json", - "selector": { + "receipts": { "concept": "dft.local_bus_passenger_fare_receipts", - "fiscal_start": "2024-04-01", - "geography_id": "E12000007" - } + "geography_id": "E12000007", + "resource": "dft_bus_value_anchors.json" + }, + "series": "bus_in_london", + "trips_basis": "published_series_rate", + "trips_concept": "dft.bus_in_london_trips_per_person" }, { - "allocation": "income_quintile_trips", - "allocation_concept": "dft.other_local_bus_trips_per_person", - "allocation_period_value": 2024, - "allocation_resource": "dft_bus_value_anchors.json", + "boardings": { + "concept": "dft.local_bus_passenger_journeys", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, + "concessionary": { + "concept": "dft.local_bus_passenger_journeys", + "dimension_values": { + "journey_category": "total_concessionary" + }, + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_journeys.json" + }, "label": "england_outside_london", + "population_geography_ids": [ + "E12000001", + "E12000002", + "E12000003", + "E12000004", + "E12000005", + "E12000006", + "E12000007", + "E12000008", + "E12000009" + ], + "receipts": { + "concept": "dft.local_bus_passenger_fare_receipts", + "geography_id": "dft:england_outside_london", + "resource": "dft_bus_value_anchors.json" + }, "regions": [ "NORTH_EAST", "NORTH_WEST", @@ -3356,56 +3511,104 @@ "EAST_MIDLANDS", "WEST_MIDLANDS", "EAST_OF_ENGLAND", + "LONDON", "SOUTH_EAST", "SOUTH_WEST" ], - "resource": "dft_bus_value_anchors.json", - "selector": { - "concept": "dft.local_bus_passenger_fare_receipts", - "fiscal_start": "2024-04-01", - "geography_id": "dft:england_outside_london" - } + "series": "other_local_bus", + "trips_basis": "published_series_rate", + "trips_concept": "dft.other_local_bus_trips_per_person" }, { - "allocation": "uniform", + "boardings": { + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, + "concessionary": { + "concept": "scotgov.bus.passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + }, + "groupby_value_id": "concessionary_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, "label": "scotland", + "population_geography_ids": [ + "S92000003" + ], + "receipts": { + "concept": "scotgov.bus.operator_revenue", + "dimension_values": { + "revenue_component": "passenger_revenue" + }, + "groupby_value_id": "passenger_revenue", + "resource": "devolved_bus_finance.json" + }, "regions": [ "SCOTLAND" ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "scotgov.bus.operator_revenue", - "fiscal_start": "2024-04-01", - "groupby_value_id": "passenger_revenue" - } + "series": "other_local_bus", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "trips_concept": "dft.other_local_bus_trips_per_person" }, { - "allocation": "uniform", + "boardings": { + "concept": "dfi_ni.translink_bus.passenger_journeys", + "resource": "devolved_bus_finance.json", + "sum_over": { + "service": [ + "metro_glider", + "ulsterbus" + ] + } + }, + "concessionary": { + "concept": "dfi_ni.translink_bus.full_fare_concession_passenger_journeys", + "dimension_values": { + "transport_mode": "bus", + "travel_status": "full_fare_concession" + }, + "resource": "devolved_bus_finance.json" + }, "label": "northern_ireland", - "regions": [ - "NORTHERN_IRELAND" + "population_geography_ids": [ + "N92000002" ], - "resource": "devolved_bus_finance.json", - "selector": { + "receipts": { "concept": "dfi_ni.translink_bus.passenger_receipts", - "fiscal_start": "2024-04-01", + "resource": "devolved_bus_finance.json", "sum_over": { "service": [ - "ulsterbus", - "metro_glider" + "metro_glider", + "ulsterbus" ] } - } + }, + "regions": [ + "NORTHERN_IRELAND" + ], + "series": "other_local_bus", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "trips_concept": "dft.other_local_bus_trips_per_person" } ], - "columns": [ - "bus_fare_spending" - ], - "iterations": 1, - "kind": "rake_to_vendored_facts", - "quintile_income": "hbai_household_net_income", - "scope": "users_only", - "weighted": true + "column": "bus_fare_spending", + "eligibility_column": "bus_pass_eligible", + "fiscal_start": "2024-04-01", + "kind": "price_bus_journeys", + "population_period_value": 2024, + "population_resource": "dft_bus_journeys.json", + "scope_translation": "operator receipts carry interchange boardings, non-resident and business payers, and London contactless is not separated, so the yield is per resident trip, not a fare; Wales publishes journeys but no receipts and keeps the chain's raw draw clipped to donor support", + "trip_rates_period_value": 2024, + "trip_rates_resource": "dft_bus_value_anchors.json", + "trips_columns": { + "bus_in_london": "bus_in_london_trips", + "other_local_bus": "other_local_bus_trips" + }, + "unpriced_regions": [ + "WALES" + ] }, { "drop_inputs": false, @@ -3458,6 +3661,335 @@ "stage": "lcfs_consumption", "survey": "Living Costs and Food Survey 2023-24" }, + "nts_bus_travel": { + "artifacts": [ + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "household_eul_2002-2024.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "nts_household_tab", + "runtime_sha256_required": true, + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "ukds_study_number": 5340 + }, + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "individual_eul_2002-2024.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "nts_individual_tab", + "runtime_sha256_required": true, + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "ukds_study_number": 5340 + }, + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "trip_eul_2002-2024.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "nts_trip_tab", + "runtime_sha256_required": true, + "sha256": "0000000000000000000000000000000000000000000000000000000000000000", + "size_bytes": 0, + "ukds_study_number": 5340 + }, + { + "format": "json", + "kind": "public_aggregate_reference", + "resource": "nts_trip_rates.json", + "role": "nts_trip_rates" + }, + { + "format": "json", + "kind": "public_aggregate_reference", + "resource": "nts_car_availability.json", + "role": "nts_car_availability" + }, + { + "format": "json", + "kind": "public_aggregate_reference", + "resource": "nts_bus_use_frequency.json", + "role": "nts_bus_use_frequency" + } + ], + "grain": "person", + "nonnegative_outputs": [ + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + "household_local_bus_trips" + ], + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed.", + "operations": [ + { + "age_band_edges": [ + 0, + 5, + 11, + 17, + 21, + 30, + 40, + 50, + 60, + 70 + ], + "cars_clip": [ + 0, + 5 + ], + "codebook_status": "declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback", + "codes": { + "female": 2, + "frequency": { + "1": 6, + "2": 5, + "3": 4, + "4": 3, + "5": 2, + "6": 1, + "7": 0 + }, + "income_band": { + "1": 1, + "2": 2, + "3": 3 + }, + "main_mode": { + "bus_in_london": 7, + "other_local_bus": 8 + }, + "region": { + "1": "NORTH_EAST", + "2": "NORTH_WEST", + "3": "YORKSHIRE", + "4": "EAST_MIDLANDS", + "5": "WEST_MIDLANDS", + "6": "EAST_OF_ENGLAND", + "7": "LONDON", + "8": "SOUTH_EAST", + "9": "SOUTH_WEST" + } + }, + "columns": { + "age_band": "Age_B01ID", + "cars": "NumCarVan", + "frequency": "LocalBusFreq_B01ID", + "household_id": "HouseholdID", + "household_size": "HHoldNumPeople", + "household_weight": "W2", + "income_band": "HHIncome2002_B02ID", + "individual_id": "IndividualID", + "main_mode": "MainMode_B04ID", + "region": "HHoldGOR_B02ID", + "sex": "Sex_B01ID", + "short_walk_multiplier": "JJXSC", + "survey_year": "SurveyYear", + "trip_id": "TripID", + "trip_weight": "W5xHH" + }, + "kind": "clean_nts_travel_tables", + "lowercase_columns": true, + "survey_years": [ + 2022, + 2023, + 2024 + ] + }, + { + "consumed_only": true, + "kind": "materialize_rules_engine_predictors", + "predictors": [ + "household_gross_income" + ] + }, + { + "car_availability_period_value": 2024, + "car_availability_resource": "nts_car_availability.json", + "categorical_predictors": [ + "region" + ], + "fallback": { + "age_threshold": 60, + "applied_to": "every_person", + "bands": [ + { + "id": "three_or_more_times_a_week", + "labels": [ + "3 or more times a week (%)" + ], + "trips_per_year": 208 + }, + { + "id": "once_or_twice_a_week", + "labels": [ + "Once or twice a week (%)" + ], + "trips_per_year": 78 + }, + { + "id": "less_than_weekly_more_than_twice_a_month", + "labels": [ + "Less than once a week, more than once or twice a month (%)", + "Less than once per week, more than twice a month (%)" + ], + "trips_per_year": 36 + }, + { + "id": "once_or_twice_a_month", + "labels": [ + "Once or twice a month (%)" + ], + "trips_per_year": 18 + }, + { + "id": "less_than_monthly_more_than_twice_a_year", + "labels": [ + "Less than once a month, more than once or twice a year (%)", + "Less than once a month, more than twice a year (%)" + ], + "trips_per_year": 6 + }, + { + "id": "once_or_twice_a_year", + "labels": [ + "Once or twice a year (%)" + ], + "trips_per_year": 1.5 + }, + { + "id": "less_than_once_a_year_or_never", + "labels": [ + "Less than once a year or never (%)" + ], + "trips_per_year": 0 + } + ], + "non_user_band": "less_than_once_a_year_or_never", + "older_age_band": "60 and over", + "period_value": 2024, + "resource": "nts_bus_use_frequency.json", + "share_age_coverage": "all_ages", + "share_geography": "E92000001", + "transport_mode_groupby_value_id": "local_bus", + "user_definition": "at_least_once_a_year" + }, + "income_band_edges": [ + 25000, + 50000 + ], + "kind": "impute_bus_use_band", + "n_estimators": 4, + "output": "local_bus_use_band", + "predictors": [ + "age_band", + "is_female", + "num_vehicles", + "household_size", + "income_band", + "region" + ], + "region_remap": { + "NORTHERN_IRELAND": "NORTH_EAST", + "SCOTLAND": "NORTH_EAST", + "WALES": "SOUTH_WEST" + }, + "seed": 0, + "trip_rates_period_value": 2024, + "trip_rates_resource": "nts_trip_rates.json" + }, + { + "annualisation_weeks": 52.14, + "band_midpoints": { + "less_than_monthly_more_than_twice_a_year": 6, + "less_than_once_a_year_or_never": 0, + "less_than_weekly_more_than_twice_a_month": 36, + "once_or_twice_a_month": 18, + "once_or_twice_a_week": 78, + "once_or_twice_a_year": 1.5, + "three_or_more_times_a_week": 208 + }, + "household_output": "household_local_bus_trips", + "kind": "assign_trips_from_band_means", + "outputs": [ + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips" + ], + "trip_rates_period_value": 2024, + "trip_rates_resource": "nts_trip_rates.json" + }, + { + "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield", + "kind": "assign_bus_pass_eligibility", + "output": "bus_pass_eligible", + "rules": { + "england_outside_london": { + "min_age": 66, + "regions": [ + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST" + ] + }, + "london": { + "max_age_exclusive": 18, + "min_age": 60, + "regions": [ + "LONDON" + ] + }, + "northern_ireland": { + "min_age": 65, + "regions": [ + "NORTHERN_IRELAND" + ] + }, + "scotland": { + "max_age_exclusive": 22, + "min_age": 60, + "regions": [ + "SCOTLAND" + ] + }, + "wales": { + "min_age": 60, + "regions": [ + "WALES" + ] + } + } + }, + { + "kind": "support_clip", + "range": "donor_realized" + } + ], + "outputs": [ + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + "bus_pass_eligible", + "household_local_bus_trips" + ], + "rewrites": [], + "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.", + "stage": "nts_bus_travel", + "survey": "National Travel Survey 2002-2024" + }, "regional_property_uprating": { "artifacts": [ { diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_household.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_household.csv new file mode 100644 index 000000000..73940fc3a --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_household.csv @@ -0,0 +1,65 @@ +HouseholdID,SurveyYear,HHoldGOR_B02ID,HHIncome2002_B02ID,NumCarVan,HHoldNumPeople,W2 +1000,2022,1,1,0,1,1 +1001,2023,2,2,1,2,1.1000000000000001 +1002,2024,3,3,2,3,1.2 +1003,2022,4,1,3,4,1.3 +1004,2023,5,2,0,1,1.3999999999999999 +1005,2024,6,3,1,2,1.5 +1006,2022,7,1,2,3,1.6000000000000001 +1007,2023,8,2,3,4,1 +1008,2024,9,3,0,1,1.1000000000000001 +1009,2022,1,1,1,2,1.2 +1010,2023,2,2,2,3,1.3 +1011,2024,3,3,3,4,1.3999999999999999 +1012,2022,4,1,0,1,1.5 +1013,2023,5,2,1,2,1.6000000000000001 +1014,2024,6,3,2,3,1 +1015,2022,7,1,3,4,1.1000000000000001 +1016,2023,8,2,0,1,1.2 +1017,2024,9,3,1,2,1.3 +1018,2022,1,1,2,3,1.3999999999999999 +1019,2023,2,2,3,4,1.5 +1020,2024,3,3,0,1,1.6000000000000001 +1021,2022,4,1,1,2,1 +1022,2023,5,2,2,3,1.1000000000000001 +1023,2024,6,3,3,4,1.2 +1024,2022,7,1,0,1,1.3 +1025,2023,8,2,1,2,1.3999999999999999 +1026,2024,9,3,2,3,1.5 +1027,2022,1,1,3,4,1.6000000000000001 +1028,2023,2,2,0,1,1 +1029,2024,3,3,1,2,1.1000000000000001 +1030,2022,4,1,2,3,1.2 +1031,2023,5,2,3,4,1.3 +1032,2024,6,3,0,1,1.3999999999999999 +1033,2022,7,1,1,2,1.5 +1034,2023,8,2,2,3,1.6000000000000001 +1035,2024,9,3,3,4,1 +1036,2022,1,1,0,1,1.1000000000000001 +1037,2023,2,2,1,2,1.2 +1038,2024,3,3,2,3,1.3 +1039,2022,4,1,3,4,1.3999999999999999 +1040,2023,5,2,0,1,1.5 +1041,2024,6,3,1,2,1.6000000000000001 +1042,2022,7,1,2,3,1 +1043,2023,8,2,3,4,1.1000000000000001 +1044,2024,9,3,0,1,1.2 +1045,2022,1,1,1,2,1.3 +1046,2023,2,2,2,3,1.3999999999999999 +1047,2024,3,3,3,4,1.5 +1048,2022,4,1,0,1,1.6000000000000001 +1049,2023,5,2,1,2,1 +1050,2024,6,3,2,3,1.1000000000000001 +1051,2022,7,1,3,4,1.2 +1052,2023,8,2,0,1,1.3 +1053,2024,9,3,1,2,1.3999999999999999 +1054,2022,1,1,2,3,1.5 +1055,2023,2,2,3,4,1.6000000000000001 +1056,2024,3,3,0,1,1 +1057,2022,4,1,1,2,1.1000000000000001 +1058,2023,5,2,2,3,1.2 +1059,2024,6,3,3,4,1.3 +1060,2022,7,1,0,1,1.3999999999999999 +1061,2023,8,2,1,2,1.5 +1062,2024,9,3,2,3,1.6000000000000001 +1063,2022,1,1,3,4,1 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv new file mode 100644 index 000000000..8cf9276bd --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv @@ -0,0 +1,161 @@ +IndividualID,HouseholdID,Age_B01ID,Sex_B01ID,LocalBusFreq_B01ID +10000,1000,1,1,5 +10010,1001,1,1,1 +10011,1001,2,2,2 +10020,1002,1,1,4 +10021,1002,2,2,5 +10022,1002,3,1,6 +10030,1003,1,1,7 +10031,1003,2,2,1 +10032,1003,3,1,2 +10033,1003,4,2,3 +10040,1004,1,1,3 +10050,1005,1,1,6 +10051,1005,2,2,7 +10060,1006,1,1,2 +10061,1006,2,2,3 +10062,1006,3,1,4 +10070,1007,1,1,5 +10071,1007,2,2,6 +10072,1007,3,1,7 +10073,1007,4,2,1 +10080,1008,1,1,1 +10090,1009,1,1,4 +10091,1009,2,2,5 +10100,1010,1,1,7 +10101,1010,2,2,1 +10102,1010,3,1,2 +10110,1011,1,1,3 +10111,1011,2,2,4 +10112,1011,3,1,5 +10113,1011,4,2,6 +10120,1012,1,1,6 +10130,1013,1,1,2 +10131,1013,2,2,3 +10140,1014,1,1,5 +10141,1014,2,2,6 +10142,1014,3,1,7 +10150,1015,1,1,1 +10151,1015,2,2,2 +10152,1015,3,1,3 +10153,1015,4,2,4 +10160,1016,1,1,4 +10170,1017,1,1,7 +10171,1017,2,2,1 +10180,1018,1,1,3 +10181,1018,2,2,4 +10182,1018,3,1,5 +10190,1019,1,1,6 +10191,1019,2,2,7 +10192,1019,3,1,1 +10193,1019,4,2,2 +10200,1020,1,1,2 +10210,1021,1,1,5 +10211,1021,2,2,6 +10220,1022,1,1,1 +10221,1022,2,2,2 +10222,1022,3,1,3 +10230,1023,1,1,4 +10231,1023,2,2,5 +10232,1023,3,1,6 +10233,1023,4,2,7 +10240,1024,1,1,7 +10250,1025,1,1,3 +10251,1025,2,2,4 +10260,1026,1,1,6 +10261,1026,2,2,7 +10262,1026,3,1,1 +10270,1027,1,1,2 +10271,1027,2,2,3 +10272,1027,3,1,4 +10273,1027,4,2,5 +10280,1028,1,1,5 +10290,1029,1,1,1 +10291,1029,2,2,2 +10300,1030,1,1,4 +10301,1030,2,2,5 +10302,1030,3,1,6 +10310,1031,1,1,7 +10311,1031,2,2,1 +10312,1031,3,1,2 +10313,1031,4,2,3 +10320,1032,1,1,3 +10330,1033,1,1,6 +10331,1033,2,2,7 +10340,1034,1,1,2 +10341,1034,2,2,3 +10342,1034,3,1,4 +10350,1035,1,1,5 +10351,1035,2,2,6 +10352,1035,3,1,7 +10353,1035,4,2,1 +10360,1036,1,1,1 +10370,1037,1,1,4 +10371,1037,2,2,5 +10380,1038,1,1,7 +10381,1038,2,2,1 +10382,1038,3,1,2 +10390,1039,1,1,3 +10391,1039,2,2,4 +10392,1039,3,1,5 +10393,1039,4,2,6 +10400,1040,1,1,6 +10410,1041,1,1,2 +10411,1041,2,2,3 +10420,1042,1,1,5 +10421,1042,2,2,6 +10422,1042,3,1,7 +10430,1043,1,1,1 +10431,1043,2,2,2 +10432,1043,3,1,3 +10433,1043,4,2,4 +10440,1044,1,1,4 +10450,1045,1,1,7 +10451,1045,2,2,1 +10460,1046,1,1,3 +10461,1046,2,2,4 +10462,1046,3,1,5 +10470,1047,1,1,6 +10471,1047,2,2,7 +10472,1047,3,1,1 +10473,1047,4,2,2 +10480,1048,1,1,2 +10490,1049,1,1,5 +10491,1049,2,2,6 +10500,1050,1,1,1 +10501,1050,2,2,2 +10502,1050,3,1,3 +10510,1051,1,1,4 +10511,1051,2,2,5 +10512,1051,3,1,6 +10513,1051,4,2,7 +10520,1052,1,1,7 +10530,1053,1,1,3 +10531,1053,2,2,4 +10540,1054,1,1,6 +10541,1054,2,2,7 +10542,1054,3,1,1 +10550,1055,1,1,2 +10551,1055,2,2,3 +10552,1055,3,1,4 +10553,1055,4,2,5 +10560,1056,1,1,5 +10570,1057,1,1,1 +10571,1057,2,2,2 +10580,1058,1,1,4 +10581,1058,2,2,5 +10582,1058,3,1,6 +10590,1059,1,1,7 +10591,1059,2,2,1 +10592,1059,3,1,2 +10593,1059,4,2,3 +10600,1060,1,1,3 +10610,1061,1,1,6 +10611,1061,2,2,7 +10620,1062,1,1,2 +10621,1062,2,2,3 +10622,1062,3,1,4 +10630,1063,1,1,5 +10631,1063,2,2,6 +10632,1063,3,1,7 +10633,1063,4,2,1 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv new file mode 100644 index 000000000..c28d3e136 --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv @@ -0,0 +1,641 @@ +TripID,IndividualID,HouseholdID,MainMode_B04ID,W5xHH,JJXSC +1,10000,1000,8,1,1 +2,10000,1000,8,1.1000000000000001,1 +3,10000,1000,3,1,1 +4,10010,1001,8,1,1 +5,10010,1001,8,1.1000000000000001,1 +6,10010,1001,8,1.2,1 +7,10010,1001,8,1,1 +8,10010,1001,8,1.1000000000000001,1 +9,10010,1001,8,1.2,1 +10,10010,1001,3,1,1 +11,10011,1001,8,1,1 +12,10011,1001,8,1.1000000000000001,1 +13,10011,1001,8,1.2,1 +14,10011,1001,8,1,1 +15,10011,1001,8,1.1000000000000001,1 +16,10011,1001,3,1,1 +17,10020,1002,8,1,1 +18,10020,1002,8,1.1000000000000001,1 +19,10020,1002,8,1.2,1 +20,10020,1002,3,1,1 +21,10021,1002,8,1,1 +22,10021,1002,8,1.1000000000000001,1 +23,10021,1002,3,1,1 +24,10022,1002,8,1,1 +25,10022,1002,3,1,1 +26,10030,1003,3,1,1 +27,10031,1003,8,1,1 +28,10031,1003,8,1.1000000000000001,1 +29,10031,1003,8,1.2,1 +30,10031,1003,8,1,1 +31,10031,1003,8,1.1000000000000001,1 +32,10031,1003,8,1.2,1 +33,10031,1003,3,1,1 +34,10032,1003,8,1,1 +35,10032,1003,8,1.1000000000000001,1 +36,10032,1003,8,1.2,1 +37,10032,1003,8,1,1 +38,10032,1003,8,1.1000000000000001,1 +39,10032,1003,3,1,1 +40,10033,1003,8,1,1 +41,10033,1003,8,1.1000000000000001,1 +42,10033,1003,8,1.2,1 +43,10033,1003,8,1,1 +44,10033,1003,3,1,1 +45,10040,1004,8,1,1 +46,10040,1004,8,1.1000000000000001,1 +47,10040,1004,8,1.2,1 +48,10040,1004,8,1,1 +49,10040,1004,3,1,1 +50,10050,1005,8,1,1 +51,10050,1005,3,1,1 +52,10051,1005,3,1,1 +53,10060,1006,7,1,1 +54,10060,1006,7,1.1000000000000001,1 +55,10060,1006,7,1.2,1 +56,10060,1006,7,1,1 +57,10060,1006,7,1.1000000000000001,1 +58,10060,1006,3,1,1 +59,10061,1006,7,1,1 +60,10061,1006,7,1.1000000000000001,1 +61,10061,1006,7,1.2,1 +62,10061,1006,7,1,1 +63,10061,1006,3,1,1 +64,10062,1006,7,1,1 +65,10062,1006,7,1.1000000000000001,1 +66,10062,1006,7,1.2,1 +67,10062,1006,3,1,1 +68,10070,1007,8,1,1 +69,10070,1007,8,1.1000000000000001,1 +70,10070,1007,3,1,1 +71,10071,1007,8,1,1 +72,10071,1007,3,1,1 +73,10072,1007,3,1,1 +74,10073,1007,8,1,1 +75,10073,1007,8,1.1000000000000001,1 +76,10073,1007,8,1.2,1 +77,10073,1007,8,1,1 +78,10073,1007,8,1.1000000000000001,1 +79,10073,1007,8,1.2,1 +80,10073,1007,3,1,1 +81,10080,1008,8,1,1 +82,10080,1008,8,1.1000000000000001,1 +83,10080,1008,8,1.2,1 +84,10080,1008,8,1,1 +85,10080,1008,8,1.1000000000000001,1 +86,10080,1008,8,1.2,1 +87,10080,1008,3,1,1 +88,10090,1009,8,1,1 +89,10090,1009,8,1.1000000000000001,1 +90,10090,1009,8,1.2,1 +91,10090,1009,3,1,1 +92,10091,1009,8,1,1 +93,10091,1009,8,1.1000000000000001,1 +94,10091,1009,3,1,1 +95,10100,1010,3,1,1 +96,10101,1010,8,1,1 +97,10101,1010,8,1.1000000000000001,1 +98,10101,1010,8,1.2,1 +99,10101,1010,8,1,1 +100,10101,1010,8,1.1000000000000001,1 +101,10101,1010,8,1.2,1 +102,10101,1010,3,1,1 +103,10102,1010,8,1,1 +104,10102,1010,8,1.1000000000000001,1 +105,10102,1010,8,1.2,1 +106,10102,1010,8,1,1 +107,10102,1010,8,1.1000000000000001,1 +108,10102,1010,3,1,1 +109,10110,1011,8,1,1 +110,10110,1011,8,1.1000000000000001,1 +111,10110,1011,8,1.2,1 +112,10110,1011,8,1,1 +113,10110,1011,3,1,1 +114,10111,1011,8,1,1 +115,10111,1011,8,1.1000000000000001,1 +116,10111,1011,8,1.2,1 +117,10111,1011,3,1,1 +118,10112,1011,8,1,1 +119,10112,1011,8,1.1000000000000001,1 +120,10112,1011,3,1,1 +121,10113,1011,8,1,1 +122,10113,1011,3,1,1 +123,10120,1012,8,1,1 +124,10120,1012,3,1,1 +125,10130,1013,8,1,1 +126,10130,1013,8,1.1000000000000001,1 +127,10130,1013,8,1.2,1 +128,10130,1013,8,1,1 +129,10130,1013,8,1.1000000000000001,1 +130,10130,1013,3,1,1 +131,10131,1013,8,1,1 +132,10131,1013,8,1.1000000000000001,1 +133,10131,1013,8,1.2,1 +134,10131,1013,8,1,1 +135,10131,1013,3,1,1 +136,10140,1014,8,1,1 +137,10140,1014,8,1.1000000000000001,1 +138,10140,1014,3,1,1 +139,10141,1014,8,1,1 +140,10141,1014,3,1,1 +141,10142,1014,3,1,1 +142,10150,1015,7,1,1 +143,10150,1015,7,1.1000000000000001,1 +144,10150,1015,7,1.2,1 +145,10150,1015,7,1,1 +146,10150,1015,7,1.1000000000000001,1 +147,10150,1015,7,1.2,1 +148,10150,1015,3,1,1 +149,10151,1015,7,1,1 +150,10151,1015,7,1.1000000000000001,1 +151,10151,1015,7,1.2,1 +152,10151,1015,7,1,1 +153,10151,1015,7,1.1000000000000001,1 +154,10151,1015,3,1,1 +155,10152,1015,7,1,1 +156,10152,1015,7,1.1000000000000001,1 +157,10152,1015,7,1.2,1 +158,10152,1015,7,1,1 +159,10152,1015,3,1,1 +160,10153,1015,7,1,1 +161,10153,1015,7,1.1000000000000001,1 +162,10153,1015,7,1.2,1 +163,10153,1015,3,1,1 +164,10160,1016,8,1,1 +165,10160,1016,8,1.1000000000000001,1 +166,10160,1016,8,1.2,1 +167,10160,1016,3,1,1 +168,10170,1017,3,1,1 +169,10171,1017,8,1,1 +170,10171,1017,8,1.1000000000000001,1 +171,10171,1017,8,1.2,1 +172,10171,1017,8,1,1 +173,10171,1017,8,1.1000000000000001,1 +174,10171,1017,8,1.2,1 +175,10171,1017,3,1,1 +176,10180,1018,8,1,1 +177,10180,1018,8,1.1000000000000001,1 +178,10180,1018,8,1.2,1 +179,10180,1018,8,1,1 +180,10180,1018,3,1,1 +181,10181,1018,8,1,1 +182,10181,1018,8,1.1000000000000001,1 +183,10181,1018,8,1.2,1 +184,10181,1018,3,1,1 +185,10182,1018,8,1,1 +186,10182,1018,8,1.1000000000000001,1 +187,10182,1018,3,1,1 +188,10190,1019,8,1,1 +189,10190,1019,3,1,1 +190,10191,1019,3,1,1 +191,10192,1019,8,1,1 +192,10192,1019,8,1.1000000000000001,1 +193,10192,1019,8,1.2,1 +194,10192,1019,8,1,1 +195,10192,1019,8,1.1000000000000001,1 +196,10192,1019,8,1.2,1 +197,10192,1019,3,1,1 +198,10193,1019,8,1,1 +199,10193,1019,8,1.1000000000000001,1 +200,10193,1019,8,1.2,1 +201,10193,1019,8,1,1 +202,10193,1019,8,1.1000000000000001,1 +203,10193,1019,3,1,1 +204,10200,1020,8,1,1 +205,10200,1020,8,1.1000000000000001,1 +206,10200,1020,8,1.2,1 +207,10200,1020,8,1,1 +208,10200,1020,8,1.1000000000000001,1 +209,10200,1020,3,1,1 +210,10210,1021,8,1,1 +211,10210,1021,8,1.1000000000000001,1 +212,10210,1021,3,1,1 +213,10211,1021,8,1,1 +214,10211,1021,3,1,1 +215,10220,1022,8,1,1 +216,10220,1022,8,1.1000000000000001,1 +217,10220,1022,8,1.2,1 +218,10220,1022,8,1,1 +219,10220,1022,8,1.1000000000000001,1 +220,10220,1022,8,1.2,1 +221,10220,1022,3,1,1 +222,10221,1022,8,1,1 +223,10221,1022,8,1.1000000000000001,1 +224,10221,1022,8,1.2,1 +225,10221,1022,8,1,1 +226,10221,1022,8,1.1000000000000001,1 +227,10221,1022,3,1,1 +228,10222,1022,8,1,1 +229,10222,1022,8,1.1000000000000001,1 +230,10222,1022,8,1.2,1 +231,10222,1022,8,1,1 +232,10222,1022,3,1,1 +233,10230,1023,8,1,1 +234,10230,1023,8,1.1000000000000001,1 +235,10230,1023,8,1.2,1 +236,10230,1023,3,1,1 +237,10231,1023,8,1,1 +238,10231,1023,8,1.1000000000000001,1 +239,10231,1023,3,1,1 +240,10232,1023,8,1,1 +241,10232,1023,3,1,1 +242,10233,1023,3,1,1 +243,10240,1024,3,1,1 +244,10250,1025,8,1,1 +245,10250,1025,8,1.1000000000000001,1 +246,10250,1025,8,1.2,1 +247,10250,1025,8,1,1 +248,10250,1025,3,1,1 +249,10251,1025,8,1,1 +250,10251,1025,8,1.1000000000000001,1 +251,10251,1025,8,1.2,1 +252,10251,1025,3,1,1 +253,10260,1026,8,1,1 +254,10260,1026,3,1,1 +255,10261,1026,3,1,1 +256,10262,1026,8,1,1 +257,10262,1026,8,1.1000000000000001,1 +258,10262,1026,8,1.2,1 +259,10262,1026,8,1,1 +260,10262,1026,8,1.1000000000000001,1 +261,10262,1026,8,1.2,1 +262,10262,1026,3,1,1 +263,10270,1027,8,1,1 +264,10270,1027,8,1.1000000000000001,1 +265,10270,1027,8,1.2,1 +266,10270,1027,8,1,1 +267,10270,1027,8,1.1000000000000001,1 +268,10270,1027,3,1,1 +269,10271,1027,8,1,1 +270,10271,1027,8,1.1000000000000001,1 +271,10271,1027,8,1.2,1 +272,10271,1027,8,1,1 +273,10271,1027,3,1,1 +274,10272,1027,8,1,1 +275,10272,1027,8,1.1000000000000001,1 +276,10272,1027,8,1.2,1 +277,10272,1027,3,1,1 +278,10273,1027,8,1,1 +279,10273,1027,8,1.1000000000000001,1 +280,10273,1027,3,1,1 +281,10280,1028,8,1,1 +282,10280,1028,8,1.1000000000000001,1 +283,10280,1028,3,1,1 +284,10290,1029,8,1,1 +285,10290,1029,8,1.1000000000000001,1 +286,10290,1029,8,1.2,1 +287,10290,1029,8,1,1 +288,10290,1029,8,1.1000000000000001,1 +289,10290,1029,8,1.2,1 +290,10290,1029,3,1,1 +291,10291,1029,8,1,1 +292,10291,1029,8,1.1000000000000001,1 +293,10291,1029,8,1.2,1 +294,10291,1029,8,1,1 +295,10291,1029,8,1.1000000000000001,1 +296,10291,1029,3,1,1 +297,10300,1030,8,1,1 +298,10300,1030,8,1.1000000000000001,1 +299,10300,1030,8,1.2,1 +300,10300,1030,3,1,1 +301,10301,1030,8,1,1 +302,10301,1030,8,1.1000000000000001,1 +303,10301,1030,3,1,1 +304,10302,1030,8,1,1 +305,10302,1030,3,1,1 +306,10310,1031,3,1,1 +307,10311,1031,8,1,1 +308,10311,1031,8,1.1000000000000001,1 +309,10311,1031,8,1.2,1 +310,10311,1031,8,1,1 +311,10311,1031,8,1.1000000000000001,1 +312,10311,1031,8,1.2,1 +313,10311,1031,3,1,1 +314,10312,1031,8,1,1 +315,10312,1031,8,1.1000000000000001,1 +316,10312,1031,8,1.2,1 +317,10312,1031,8,1,1 +318,10312,1031,8,1.1000000000000001,1 +319,10312,1031,3,1,1 +320,10313,1031,8,1,1 +321,10313,1031,8,1.1000000000000001,1 +322,10313,1031,8,1.2,1 +323,10313,1031,8,1,1 +324,10313,1031,3,1,1 +325,10320,1032,8,1,1 +326,10320,1032,8,1.1000000000000001,1 +327,10320,1032,8,1.2,1 +328,10320,1032,8,1,1 +329,10320,1032,3,1,1 +330,10330,1033,7,1,1 +331,10330,1033,3,1,1 +332,10331,1033,3,1,1 +333,10340,1034,8,1,1 +334,10340,1034,8,1.1000000000000001,1 +335,10340,1034,8,1.2,1 +336,10340,1034,8,1,1 +337,10340,1034,8,1.1000000000000001,1 +338,10340,1034,3,1,1 +339,10341,1034,8,1,1 +340,10341,1034,8,1.1000000000000001,1 +341,10341,1034,8,1.2,1 +342,10341,1034,8,1,1 +343,10341,1034,3,1,1 +344,10342,1034,8,1,1 +345,10342,1034,8,1.1000000000000001,1 +346,10342,1034,8,1.2,1 +347,10342,1034,3,1,1 +348,10350,1035,8,1,1 +349,10350,1035,8,1.1000000000000001,1 +350,10350,1035,3,1,1 +351,10351,1035,8,1,1 +352,10351,1035,3,1,1 +353,10352,1035,3,1,1 +354,10353,1035,8,1,1 +355,10353,1035,8,1.1000000000000001,1 +356,10353,1035,8,1.2,1 +357,10353,1035,8,1,1 +358,10353,1035,8,1.1000000000000001,1 +359,10353,1035,8,1.2,1 +360,10353,1035,3,1,1 +361,10360,1036,8,1,1 +362,10360,1036,8,1.1000000000000001,1 +363,10360,1036,8,1.2,1 +364,10360,1036,8,1,1 +365,10360,1036,8,1.1000000000000001,1 +366,10360,1036,8,1.2,1 +367,10360,1036,3,1,1 +368,10370,1037,8,1,1 +369,10370,1037,8,1.1000000000000001,1 +370,10370,1037,8,1.2,1 +371,10370,1037,3,1,1 +372,10371,1037,8,1,1 +373,10371,1037,8,1.1000000000000001,1 +374,10371,1037,3,1,1 +375,10380,1038,3,1,1 +376,10381,1038,8,1,1 +377,10381,1038,8,1.1000000000000001,1 +378,10381,1038,8,1.2,1 +379,10381,1038,8,1,1 +380,10381,1038,8,1.1000000000000001,1 +381,10381,1038,8,1.2,1 +382,10381,1038,3,1,1 +383,10382,1038,8,1,1 +384,10382,1038,8,1.1000000000000001,1 +385,10382,1038,8,1.2,1 +386,10382,1038,8,1,1 +387,10382,1038,8,1.1000000000000001,1 +388,10382,1038,3,1,1 +389,10390,1039,8,1,1 +390,10390,1039,8,1.1000000000000001,1 +391,10390,1039,8,1.2,1 +392,10390,1039,8,1,1 +393,10390,1039,3,1,1 +394,10391,1039,8,1,1 +395,10391,1039,8,1.1000000000000001,1 +396,10391,1039,8,1.2,1 +397,10391,1039,3,1,1 +398,10392,1039,8,1,1 +399,10392,1039,8,1.1000000000000001,1 +400,10392,1039,3,1,1 +401,10393,1039,8,1,1 +402,10393,1039,3,1,1 +403,10400,1040,8,1,1 +404,10400,1040,3,1,1 +405,10410,1041,8,1,1 +406,10410,1041,8,1.1000000000000001,1 +407,10410,1041,8,1.2,1 +408,10410,1041,8,1,1 +409,10410,1041,8,1.1000000000000001,1 +410,10410,1041,3,1,1 +411,10411,1041,8,1,1 +412,10411,1041,8,1.1000000000000001,1 +413,10411,1041,8,1.2,1 +414,10411,1041,8,1,1 +415,10411,1041,3,1,1 +416,10420,1042,7,1,1 +417,10420,1042,7,1.1000000000000001,1 +418,10420,1042,3,1,1 +419,10421,1042,7,1,1 +420,10421,1042,3,1,1 +421,10422,1042,3,1,1 +422,10430,1043,8,1,1 +423,10430,1043,8,1.1000000000000001,1 +424,10430,1043,8,1.2,1 +425,10430,1043,8,1,1 +426,10430,1043,8,1.1000000000000001,1 +427,10430,1043,8,1.2,1 +428,10430,1043,3,1,1 +429,10431,1043,8,1,1 +430,10431,1043,8,1.1000000000000001,1 +431,10431,1043,8,1.2,1 +432,10431,1043,8,1,1 +433,10431,1043,8,1.1000000000000001,1 +434,10431,1043,3,1,1 +435,10432,1043,8,1,1 +436,10432,1043,8,1.1000000000000001,1 +437,10432,1043,8,1.2,1 +438,10432,1043,8,1,1 +439,10432,1043,3,1,1 +440,10433,1043,8,1,1 +441,10433,1043,8,1.1000000000000001,1 +442,10433,1043,8,1.2,1 +443,10433,1043,3,1,1 +444,10440,1044,8,1,1 +445,10440,1044,8,1.1000000000000001,1 +446,10440,1044,8,1.2,1 +447,10440,1044,3,1,1 +448,10450,1045,3,1,1 +449,10451,1045,8,1,1 +450,10451,1045,8,1.1000000000000001,1 +451,10451,1045,8,1.2,1 +452,10451,1045,8,1,1 +453,10451,1045,8,1.1000000000000001,1 +454,10451,1045,8,1.2,1 +455,10451,1045,3,1,1 +456,10460,1046,8,1,1 +457,10460,1046,8,1.1000000000000001,1 +458,10460,1046,8,1.2,1 +459,10460,1046,8,1,1 +460,10460,1046,3,1,1 +461,10461,1046,8,1,1 +462,10461,1046,8,1.1000000000000001,1 +463,10461,1046,8,1.2,1 +464,10461,1046,3,1,1 +465,10462,1046,8,1,1 +466,10462,1046,8,1.1000000000000001,1 +467,10462,1046,3,1,1 +468,10470,1047,8,1,1 +469,10470,1047,3,1,1 +470,10471,1047,3,1,1 +471,10472,1047,8,1,1 +472,10472,1047,8,1.1000000000000001,1 +473,10472,1047,8,1.2,1 +474,10472,1047,8,1,1 +475,10472,1047,8,1.1000000000000001,1 +476,10472,1047,8,1.2,1 +477,10472,1047,3,1,1 +478,10473,1047,8,1,1 +479,10473,1047,8,1.1000000000000001,1 +480,10473,1047,8,1.2,1 +481,10473,1047,8,1,1 +482,10473,1047,8,1.1000000000000001,1 +483,10473,1047,3,1,1 +484,10480,1048,8,1,1 +485,10480,1048,8,1.1000000000000001,1 +486,10480,1048,8,1.2,1 +487,10480,1048,8,1,1 +488,10480,1048,8,1.1000000000000001,1 +489,10480,1048,3,1,1 +490,10490,1049,8,1,1 +491,10490,1049,8,1.1000000000000001,1 +492,10490,1049,3,1,1 +493,10491,1049,8,1,1 +494,10491,1049,3,1,1 +495,10500,1050,8,1,1 +496,10500,1050,8,1.1000000000000001,1 +497,10500,1050,8,1.2,1 +498,10500,1050,8,1,1 +499,10500,1050,8,1.1000000000000001,1 +500,10500,1050,8,1.2,1 +501,10500,1050,3,1,1 +502,10501,1050,8,1,1 +503,10501,1050,8,1.1000000000000001,1 +504,10501,1050,8,1.2,1 +505,10501,1050,8,1,1 +506,10501,1050,8,1.1000000000000001,1 +507,10501,1050,3,1,1 +508,10502,1050,8,1,1 +509,10502,1050,8,1.1000000000000001,1 +510,10502,1050,8,1.2,1 +511,10502,1050,8,1,1 +512,10502,1050,3,1,1 +513,10510,1051,7,1,1 +514,10510,1051,7,1.1000000000000001,1 +515,10510,1051,7,1.2,1 +516,10510,1051,3,1,1 +517,10511,1051,7,1,1 +518,10511,1051,7,1.1000000000000001,1 +519,10511,1051,3,1,1 +520,10512,1051,7,1,1 +521,10512,1051,3,1,1 +522,10513,1051,3,1,1 +523,10520,1052,3,1,1 +524,10530,1053,8,1,1 +525,10530,1053,8,1.1000000000000001,1 +526,10530,1053,8,1.2,1 +527,10530,1053,8,1,1 +528,10530,1053,3,1,1 +529,10531,1053,8,1,1 +530,10531,1053,8,1.1000000000000001,1 +531,10531,1053,8,1.2,1 +532,10531,1053,3,1,1 +533,10540,1054,8,1,1 +534,10540,1054,3,1,1 +535,10541,1054,3,1,1 +536,10542,1054,8,1,1 +537,10542,1054,8,1.1000000000000001,1 +538,10542,1054,8,1.2,1 +539,10542,1054,8,1,1 +540,10542,1054,8,1.1000000000000001,1 +541,10542,1054,8,1.2,1 +542,10542,1054,3,1,1 +543,10550,1055,8,1,1 +544,10550,1055,8,1.1000000000000001,1 +545,10550,1055,8,1.2,1 +546,10550,1055,8,1,1 +547,10550,1055,8,1.1000000000000001,1 +548,10550,1055,3,1,1 +549,10551,1055,8,1,1 +550,10551,1055,8,1.1000000000000001,1 +551,10551,1055,8,1.2,1 +552,10551,1055,8,1,1 +553,10551,1055,3,1,1 +554,10552,1055,8,1,1 +555,10552,1055,8,1.1000000000000001,1 +556,10552,1055,8,1.2,1 +557,10552,1055,3,1,1 +558,10553,1055,8,1,1 +559,10553,1055,8,1.1000000000000001,1 +560,10553,1055,3,1,1 +561,10560,1056,8,1,1 +562,10560,1056,8,1.1000000000000001,1 +563,10560,1056,3,1,1 +564,10570,1057,8,1,1 +565,10570,1057,8,1.1000000000000001,1 +566,10570,1057,8,1.2,1 +567,10570,1057,8,1,1 +568,10570,1057,8,1.1000000000000001,1 +569,10570,1057,8,1.2,1 +570,10570,1057,3,1,1 +571,10571,1057,8,1,1 +572,10571,1057,8,1.1000000000000001,1 +573,10571,1057,8,1.2,1 +574,10571,1057,8,1,1 +575,10571,1057,8,1.1000000000000001,1 +576,10571,1057,3,1,1 +577,10580,1058,8,1,1 +578,10580,1058,8,1.1000000000000001,1 +579,10580,1058,8,1.2,1 +580,10580,1058,3,1,1 +581,10581,1058,8,1,1 +582,10581,1058,8,1.1000000000000001,1 +583,10581,1058,3,1,1 +584,10582,1058,8,1,1 +585,10582,1058,3,1,1 +586,10590,1059,3,1,1 +587,10591,1059,8,1,1 +588,10591,1059,8,1.1000000000000001,1 +589,10591,1059,8,1.2,1 +590,10591,1059,8,1,1 +591,10591,1059,8,1.1000000000000001,1 +592,10591,1059,8,1.2,1 +593,10591,1059,3,1,1 +594,10592,1059,8,1,1 +595,10592,1059,8,1.1000000000000001,1 +596,10592,1059,8,1.2,1 +597,10592,1059,8,1,1 +598,10592,1059,8,1.1000000000000001,1 +599,10592,1059,3,1,1 +600,10593,1059,8,1,1 +601,10593,1059,8,1.1000000000000001,1 +602,10593,1059,8,1.2,1 +603,10593,1059,8,1,1 +604,10593,1059,3,1,1 +605,10600,1060,7,1,1 +606,10600,1060,7,1.1000000000000001,1 +607,10600,1060,7,1.2,1 +608,10600,1060,7,1,1 +609,10600,1060,3,1,1 +610,10610,1061,8,1,1 +611,10610,1061,3,1,1 +612,10611,1061,3,1,1 +613,10620,1062,8,1,1 +614,10620,1062,8,1.1000000000000001,1 +615,10620,1062,8,1.2,1 +616,10620,1062,8,1,1 +617,10620,1062,8,1.1000000000000001,1 +618,10620,1062,3,1,1 +619,10621,1062,8,1,1 +620,10621,1062,8,1.1000000000000001,1 +621,10621,1062,8,1.2,1 +622,10621,1062,8,1,1 +623,10621,1062,3,1,1 +624,10622,1062,8,1,1 +625,10622,1062,8,1.1000000000000001,1 +626,10622,1062,8,1.2,1 +627,10622,1062,3,1,1 +628,10630,1063,8,1,1 +629,10630,1063,8,1.1000000000000001,1 +630,10630,1063,3,1,1 +631,10631,1063,8,1,1 +632,10631,1063,3,1,1 +633,10632,1063,3,1,1 +634,10633,1063,8,1,1 +635,10633,1063,8,1.1000000000000001,1 +636,10633,1063,8,1.2,1 +637,10633,1063,8,1,1 +638,10633,1063,8,1.1000000000000001,1 +639,10633,1063,8,1.2,1 +640,10633,1063,3,1,1 diff --git a/packages/microcosm-graph/tests/test_acceptance_h_parity.py b/packages/microcosm-graph/tests/test_acceptance_h_parity.py index cb6053a11..774ef393a 100644 --- a/packages/microcosm-graph/tests/test_acceptance_h_parity.py +++ b/packages/microcosm-graph/tests/test_acceptance_h_parity.py @@ -43,7 +43,7 @@ #: was taken under). KERNEL_PARITY = PARITY / "kernels" -#: H2: ``uk_spine.json`` — the 30-stage FRS spine expressed as a graph — plus +#: H2: ``uk_spine.json`` — the 31-stage FRS spine expressed as a graph — plus #: ``sources/``, the data-only bundle both the graph and the legacy oracle #: rebuild their transforms from. The root transform's weights differ at the #: last bit between machines, so both sides recompute the root from the raw @@ -256,7 +256,7 @@ def test_h2_uk_spine_parity(tmp_path: Path) -> None: from declared ``consumes``: the assertion below is that the compiled topological order is derived, so the hand-maintained ``_STAGE_NAMES`` tuple in ``tools/build_uk_frs_spine.py`` — the 30 names intersected with a - 30-stage packaged manifest, kept in step by hand — can be deleted. + 31-stage packaged manifest, kept in step by hand — can be deleted. """ _require(UK_SPINE_PARITY, "the UK migration lane (charter H2, María reviews)") diff --git a/tools/build_uk_frs_spine.py b/tools/build_uk_frs_spine.py index 48bf36e9f..5e26dfb75 100644 --- a/tools/build_uk_frs_spine.py +++ b/tools/build_uk_frs_spine.py @@ -113,6 +113,7 @@ UK_SAMPLE_RUNG_TOKENS, UK_SAMPLE_SEED_DEFAULT, ) +from microcosm.build.uk_runtime.nts_bus_travel import UKNTSBusTravelStageTransform from microcosm.build.uk_runtime.regional_uprating import ( UKRegionalPropertyUpratingStageTransform, ) @@ -268,6 +269,21 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: type=Path, help="Caller-supplied private WAS round-8 household tab for was_wealth.", ) + parser.add_argument( + "--nts-household-tab", + type=Path, + help="Caller-supplied private NTS household tab for nts_bus_travel.", + ) + parser.add_argument( + "--nts-individual-tab", + type=Path, + help="Caller-supplied private NTS individual tab for nts_bus_travel.", + ) + parser.add_argument( + "--nts-trip-tab", + type=Path, + help="Caller-supplied private NTS trip tab for nts_bus_travel.", + ) parser.add_argument( "--lcfs-hh-tab", type=Path, @@ -321,6 +337,9 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: flag for flag, value in ( ("--was-tab", args.was_tab), + ("--nts-household-tab", args.nts_household_tab), + ("--nts-individual-tab", args.nts_individual_tab), + ("--nts-trip-tab", args.nts_trip_tab), ("--lcfs-hh-tab", args.lcfs_hh_tab), ("--lcfs-person-tab", args.lcfs_person_tab), ("--etb-tab", args.etb_tab), @@ -423,6 +442,9 @@ def _synthetic_graph_sources(source: Path) -> dict[str, Path]: raise ValueError("Synthetic fixture inputs must be an object.") names = { "was": "was", + "nts_household": "nts_household", + "nts_individual": "nts_individual", + "nts_trip": "nts_trip", "lcfs_household": "lcfs_household", "lcfs_person": "lcfs_person", "etb": "etb", @@ -1343,6 +1365,21 @@ def main(argv: list[str] | None = None) -> int: raise ValueError( "--was-tab is required when the was_wealth stage is scheduled." ) + if args.synthetic_fixture_dir is None and "nts_bus_travel" in stage_names: + missing_nts = [ + flag + for flag, value in ( + ("--nts-household-tab", args.nts_household_tab), + ("--nts-individual-tab", args.nts_individual_tab), + ("--nts-trip-tab", args.nts_trip_tab), + ) + if value is None + ] + if missing_nts: + raise ValueError( + "nts_bus_travel requires caller-supplied private inputs: " + f"{', '.join(missing_nts)}." + ) if args.synthetic_fixture_dir is None and "lcfs_consumption" in stage_names: missing_lcfs = [ flag @@ -1480,6 +1517,16 @@ def main(argv: list[str] | None = None) -> int: was_tab_path=sources["was"], ) ) + if "nts_bus_travel" in stage_names: + implementations["nts_bus_travel"] = _GraphSourceTransform( + lambda sources: UKNTSBusTravelStageTransform( + stage=stages_by_name["nts_bus_travel"], + engine=engine, + nts_household_tab_path=sources["nts_household"], + nts_individual_tab_path=sources["nts_individual"], + nts_trip_tab_path=sources["nts_trip"], + ) + ) if "regional_property_uprating" in stage_names: implementations["regional_property_uprating"] = ( UKRegionalPropertyUpratingStageTransform( @@ -1643,6 +1690,10 @@ def main(argv: list[str] | None = None) -> int: graph_sources = {"frs": args.frs_raw_dir} if "was_wealth" in stage_names: graph_sources["was"] = args.was_tab + if "nts_bus_travel" in stage_names: + graph_sources["nts_household"] = args.nts_household_tab + graph_sources["nts_individual"] = args.nts_individual_tab + graph_sources["nts_trip"] = args.nts_trip_tab if "lcfs_consumption" in stage_names: graph_sources["lcfs_household"] = args.lcfs_hh_tab graph_sources["lcfs_person"] = args.lcfs_person_tab diff --git a/tools/build_uk_release_input_coverage_manifest.py b/tools/build_uk_release_input_coverage_manifest.py index 822960d34..6bb6da1c9 100644 --- a/tools/build_uk_release_input_coverage_manifest.py +++ b/tools/build_uk_release_input_coverage_manifest.py @@ -823,6 +823,10 @@ def build_manifest( stage_name="was_wealth", candidate_source=candidate_source, ), + "nts_bus_travel": _source_stage_family_coverage_contract( + stage_name="nts_bus_travel", + candidate_source=candidate_source, + ), "regional_property_uprating": _source_stage_family_coverage_contract( stage_name="regional_property_uprating", candidate_source=candidate_source, diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index 09742b065..a4baae73e 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 """Regenerate the hermetic charter-H2 UK spine parity fixture. -The oracle is the legacy :class:`microcosm.build.plan.StagePlan`: all 30 +The oracle is the legacy :class:`microcosm.build.plan.StagePlan`: all 31 stages are the current production transform classes. Private source files are replaced only through their supported parsed-input seams. The bundle's ``fixture.json`` is deliberately data-only so the graph's unbound UK registry @@ -93,6 +93,7 @@ BUS_FARE_LCFS_CODES, UKLCFSConsumptionStageTransform, ) +from microcosm.build.uk_runtime.nts_bus_travel import UKNTSBusTravelStageTransform from microcosm.build.uk_runtime.regional_uprating import ( UKRegionalPropertyUpratingStageTransform, ) @@ -141,7 +142,7 @@ _QRF_ESTIMATORS = 4 # These are the complete object-string surface observed in the unchanged -# legacy 30-stage output. Graph storage uses pandas StringDtype/python. +# legacy 31-stage output. Graph storage uses pandas StringDtype/python. _NORMALIZED_STRING_COLUMNS: Mapping[str, tuple[str, ...]] = { "person": ( "gender", @@ -670,6 +671,82 @@ def _lcfs_donors() -> tuple[pd.DataFrame, pd.DataFrame]: return pd.DataFrame(household), person +def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: + """Synthetic NTS Household, Individual and Trip tables (2022-2024). + + Column names and codes follow the stage's declared codebook: nine English + GOR codes, the three income bands, W2 household weights, banded ages, + the interview frequency band (1 = 3+ a week ... 7 = less than yearly or + never) and diary trips whose main mode is bus in London (7) or other + local bus (8), each with the trip weight and the short-walk multiplier. + """ + + households = _DONOR_ROWS + rows = np.arange(households, dtype=int) + household = pd.DataFrame( + { + "HouseholdID": 1000 + rows, + "SurveyYear": 2022 + rows % 3, + "HHoldGOR_B02ID": 1 + rows % 9, + "HHIncome2002_B02ID": 1 + rows % 3, + "NumCarVan": rows % 4, + "HHoldNumPeople": 1 + rows % 4, + "W2": 1.0 + (rows % 7) / 10.0, + } + ) + person_rows = [] + for household_id, size in zip( + household["HouseholdID"], household["HHoldNumPeople"], strict=True + ): + for member in range(int(size)): + index = int(household_id) * 10 + member + person_rows.append( + { + "IndividualID": index, + "HouseholdID": int(household_id), + "Age_B01ID": 1 + (index % 10), + "Sex_B01ID": 1 + (index % 2), + # Frequent riders in the low-income, car-free households; + # the never band elsewhere, with every band populated. + "LocalBusFreq_B01ID": 1 + (index % 7), + } + ) + individual = pd.DataFrame(person_rows) + trip_rows = [] + trip_id = 1 + for _, person in individual.iterrows(): + band = int(person["LocalBusFreq_B01ID"]) + # More trips for the frequent bands, none for the never band. + trips = max(0, 7 - band) if band < 7 else 0 + london = (int(person["HouseholdID"]) - 1000) % 9 == 6 + for t in range(trips): + trip_rows.append( + { + "TripID": trip_id, + "IndividualID": int(person["IndividualID"]), + "HouseholdID": int(person["HouseholdID"]), + "MainMode_B04ID": 7 if london else 8, + "W5xHH": 1.0 + (t % 3) / 10.0, + "JJXSC": 1.0, + } + ) + trip_id += 1 + # One non-bus trip per person so the mode filter is exercised. + trip_rows.append( + { + "TripID": trip_id, + "IndividualID": int(person["IndividualID"]), + "HouseholdID": int(person["HouseholdID"]), + "MainMode_B04ID": 3, + "W5xHH": 1.0, + "JJXSC": 1.0, + } + ) + trip_id += 1 + trip = pd.DataFrame(trip_rows) + return household, individual, trip + + def _etb_donor() -> pd.DataFrame: rows = np.arange(_DONOR_ROWS, dtype=float) return pd.DataFrame( @@ -949,6 +1026,10 @@ def _fixture_stages( stage = _replace_operation( stage, "fit_weighted_qrf_chain", n_estimators=_QRF_ESTIMATORS ) + elif stage.stage == "nts_bus_travel": + stage = _replace_operation( + stage, "impute_bus_use_band", n_estimators=_QRF_ESTIMATORS + ) elif stage.stage == "lcfs_consumption": stage = _replace_operation( stage, "fit_weighted_qrf_chain", n_estimators=_QRF_ESTIMATORS @@ -1105,6 +1186,9 @@ def _build_implementations( stages: Mapping[str, SourceStageSpec], raw_dir: Path, was: pd.DataFrame, + nts_household: pd.DataFrame, + nts_individual: pd.DataFrame, + nts_trip: pd.DataFrame, lcfs_household: pd.DataFrame, lcfs_person: pd.DataFrame, etb: pd.DataFrame, @@ -1172,6 +1256,13 @@ def capture_root(frame: Frame) -> Frame: "was_wealth": UKWASWealthStageTransform( stage=stages["was_wealth"], engine=engine, donor=was ), + "nts_bus_travel": UKNTSBusTravelStageTransform( + stage=stages["nts_bus_travel"], + engine=engine, + nts_household=nts_household, + nts_individual=nts_individual, + nts_trip=nts_trip, + ), "regional_property_uprating": UKRegionalPropertyUpratingStageTransform( stage=stages["regional_property_uprating"] ), @@ -1247,7 +1338,7 @@ def _run_legacy_plan( stages: Iterable[SourceStageSpec], implementations: Mapping[str, object], ) -> Frame: - """Run the legacy 30-stage StagePlan oracle and return its final frame.""" + """Run the legacy 31-stage StagePlan oracle and return its final frame.""" stages = tuple(stages) committed = load_country_spec("uk") @@ -1280,7 +1371,7 @@ def _run_legacy_plan( def legacy_oracle_frame(fixture: Path) -> Frame: """The legacy oracle's final frame on the fixture, computed live. - Rebuilds the same 30 transforms the graph's UK registry reconstructs from + Rebuilds the same 31 transforms the graph's UK registry reconstructs from ``fixture/sources``, runs them through the legacy StagePlan in this process, root included, and applies the one string normalization the fixture documents. The content identity is a byte-exact fingerprint of @@ -1317,10 +1408,14 @@ def generate(output: Path) -> None: stage_map = {stage.stage: stage for stage in stages} was = _was_donor() + nts_household, nts_individual, nts_trip = _nts_donors() lcfs_household, lcfs_person = _lcfs_donors() etb = _etb_donor() spi_donor = _spi_donor() _write_csv(sources / "was.csv", was) + _write_csv(sources / "nts_household.csv", nts_household) + _write_csv(sources / "nts_individual.csv", nts_individual) + _write_csv(sources / "nts_trip.csv", nts_trip) _write_csv(sources / "lcfs_household.csv", lcfs_household) _write_csv(sources / "lcfs_person.csv", lcfs_person) _write_csv(sources / "etb.csv", etb) @@ -1341,6 +1436,9 @@ def generate(output: Path) -> None: stages=stage_map, raw_dir=raw_dir, was=was, + nts_household=nts_household, + nts_individual=nts_individual, + nts_trip=nts_trip, lcfs_household=lcfs_household, lcfs_person=lcfs_person, etb=etb, @@ -1378,7 +1476,7 @@ def generate(output: Path) -> None: descriptor = { "schema_version": "uk-spine-parity-fixture.v1", "description": ( - "Data-only inputs for reconstructing the same 30 current UK stage " + "Data-only inputs for reconstructing the same 31 current UK stage " "transform classes used by the legacy StagePlan oracle." ), "stages": {stage.stage: _stage_payload(stage) for stage in stages}, @@ -1391,6 +1489,9 @@ def generate(output: Path) -> None: "inputs": { "frs_raw": "frs_raw", "was": "was.csv", + "nts_household": "nts_household.csv", + "nts_individual": "nts_individual.csv", + "nts_trip": "nts_trip.csv", "lcfs_household": "lcfs_household.csv", "lcfs_person": "lcfs_person.csv", "etb": "etb.csv", From 4010cb592a3ceb9aff4a1e0415fdca75f28ea8af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:06:25 +0100 Subject: [PATCH 05/19] Add the #930 receipts: Chronicle landing and re-pin, the #927 carry-overs, the stretch instrument, the stage and pricing declarations, the licensed measurement pending (#930 C9) Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 168 +++++++++++++++++++ 1 file changed, 168 insertions(+) create mode 100644 experiments/930-nts-bus-journeys-receipts.md diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md new file mode 100644 index 000000000..144bc5a67 --- /dev/null +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -0,0 +1,168 @@ +# #930 receipts — local bus journeys from the NTS microdata, priced at the published yield + +Plan: `repos/uk-930-implementation-plan.md` (approved 2026-09-17; María's rulings: Chronicle +facts first, price per fare-paying boarding on the landed BUS01 and concessionary facts with a +declared boardings-per-resident-trip translation, statutory age eligibility at zero fare, Wales +keeps the raw LCFS draw, the ONS 04.5 sign-out stands). This is the structural fix ruled on +2026-09-15 (#890 receipts Part R) for the rake-then-bind bus fares PR #927 merged with. Worktree +`repos/populace-930`, branch `uk-930-nts-bus` on main `7c4a5ac0`. Licensed evidence, once the +NTS tabs land, goes under `data/ukds/acceptance/930-nts-bus/` (SDC-safe aggregates only); this +file carries the digest-pinned receipts the declarations anchor to. + +## Part A — Chronicle landing and the feed re-pin (C2 + C3, commit `f7540332`) + +`PolicyEngine/chronicle#274` (posted 2026-09-17 on plan approval) asked for the DfT BUS01 +passenger journeys and concessionary journeys by area, the BUS05 operating-revenue components, +NTS0303/NTS0601 trip rates and the devolved concessionary journeys. Chronicle PR #275 landed +them at `78466057401af48f9a53da41b87295241e4af1ba`. Feed rebuilt from that commit with +`chronicle build-bundle --suite uk` → `build-consumer-artifact`: + +- `consumer_facts.jsonl` sha256 `8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a` +- `manifest.json` sha256 `0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2` +- rows / schema: 277,183 / `policyengine_ledger.consumer_artifact.v2`, consumer-fact schema + `chronicle.consumer_fact.v3` (`bdb51e2a…`) +- previous national pin: `ec200856` (the #927 pin); copies of the artifact at + `data/ukds/acceptance/chronicle-uk-artifact-7846605/` and `.codex-work/` in the worktree + +Effect on the committed national and local surfaces before any binding change: none. The +generators regenerate byte-identical apart from the membership feed label +(`chronicle-uk-ec200856-consumer-facts` → `chronicle-uk-78466057-consumer-facts`); the +`docs/uk-chronicle-feed-repin.md` order was followed (vendoring before the generators; the +three new resources were undeclared in `country_package.json` while first vendored, since the +loader refuses a declared resource that does not exist yet). + +Vendored resources (`tools/vendor_uk_ledger_facts.py`, `--check` clean on the pin): + +- `dft_bus_journeys.json` — 197 rows: BUS01a journeys by area FY2005–2025 (39, thirteen areas + by three years), BUS01c concessionary journeys by area and `journey_category` + (elderly_disabled_concessionary, total_concessionary; 78), the nine BUS05i revenue components + by area (54), ONS mid-year population for England, its regions, Scotland and Northern Ireland + (26); sha256 `f67d0b92…`; consumers `uk_runtime.lcfs_consumption`, `uk_runtime.bus_fare_pricing`, + `uk_runtime.etb_services`, `uk_runtime.bus_support_per_journey` +- `nts_trip_rates.json` — 90 rows: NTS0303 trips per person by main mode and `dft.survey_year` + (9), NTS0601 by `dft.age_band` and mode (81); sha256 `377f811c…`; consumer + `uk_runtime.nts_bus_travel` +- `nts_car_availability.json` — 6 rows: NTS0205 household car availability shares, England 2024 + and 2023; sha256 `bdef4153…`; consumer `uk_runtime.nts_bus_travel` +- `devolved_bus_finance.json` gains the six DfI + `dfi_ni.translink_bus.full_fare_concession_passenger_journeys` rows +- `dft_bus_value_anchors.json`: the NTS0705a selection is pinned to + `groupby_dimension: dft.household_income_quintile` (the feed now carries a second NTS0705a + breakdown), so its 24 rows and the #927 targets are unchanged +- `nts_bus_use_frequency.json`: consumers are now `uk_runtime.bus_use_incidence` (the NTS0313 + fact-check helper) and `uk_runtime.nts_bus_travel`; the lcfs stage no longer reads it + +DfT labels fiscal years by the closing year, so every FY2024-25 selection here is by +`fiscal_start: 2024-04-01`, never by label. + +## Part B — Vahid's third pass on PR #927 (C0, commit `5326ab68`) + +All nine items closed, none of which changed a value: the stale "FY2024-25 Ofgem pricing set +their level" sentence (stage notes, packaged mirror, H2 fixture, the #890 changelog fragment); +the `price_domestic_energy` schema branch's conditional connection keys (the first `if`/`then` +in `sources.schema.json`; `validate_and_inject_defaults` honours it); the declared +`connection_fallback_regions: [NORTHERN_IRELAND]` refused at runtime if the crosswalk differs; +per-sweep IPF residuals (`raking_sweep_residuals` → the energy receipt's `sweep_residuals`) with +the tolerance-governance and connection-cap sentences on the `energy_rake` gate note; the +gas-connection walk documented as the greedy weight-fitting walk it is, with the unequal-weights +skip test; the `evidence_absent_blocks` plus `synthetic_smoke` seam test; #890 receipts Parts R +and S re-attributed to the rebased `713b5064`, Part T recording that ONS 04.5.3 and 04.5.4 +(about GBP 1.57bn) are vendored and unbound and that María confirmed the 04.5 sign-out; PR +#927's body edited with the rebased hashes. + +## Part C — the weight-stretch instrument (C1, commit `52e363bd`) + +`calibration_run.py` writes `target_support_matrix.npz`, `target_support_vectors.npz` and +`target_support_manifest.json` beside the diagnostics before `_run_calibration_gate_battery` +(`uk_runtime/target_support.py::write_uk_target_support_sidecars`), so a blocked attempt keeps +its anatomy readable; the staging H5 posture is unchanged. `tools/diagnose_uk_target_support.py` +decomposes any compiled target: target, design and final aggregates, carriers, top-carrier +concentration, the carrier weight-ratio distribution, the share of the target's final mass on +households stretched beyond 3x and 5x their design weight (each beside the frame-wide share), +and the near-cap fraction, with the recomputed final estimates verified against the attempt's +diagnostics. This is the never-measured #890 acceptance line (England bus-fare mass on +households stretched more than 3x) and #930's measurement, to be read on the first calibration +round after the tabs land. + +## Part D — the stage, the pricing and the support-side fence (C4–C7, unit-level receipts) + +Declarations and runtime, every publisher number reaching the stages through `vendored_rows`: + +- `nts_bus_travel` (person grain, between `was_wealth` and `lcfs_consumption`; 32 declared + stages, 30 on the H2 fixture): `clean_nts_travel_tables` on the Household, Individual and Trip + tabs (UKDS SN 5340, End User Licence; England residents only since 2013) through a declared + codebook; one regime-gated QRF on the interview frequency band (`impute_bus_use_band`, + identity-keyed uniforms, rounded to the ordinal; devolved recipients on a declared proxy + region); `assign_trips_from_band_means` (W5 × JJXSC trips over W2 persons, × 52.14, per band × + residence group, split into `bus_in_london_trips` and `other_local_bus_trips`, summed to + `household_local_bus_trips`); `assign_bus_pass_eligibility` (England outside London 66+, + London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 65+). If the + extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares + and declared midpoints scaled to the vendored NTS0303 rate, receipted. Gates + `uk_stage_nts_bus_travel_support` (support clip) and `uk_stage_nts_bus_travel_facts` + (`bus_travel_facts`, population fact check: user share within 0.05 of NTS0313, trips per + person within 15 % of NTS0303, period 2024); NTS0205 car availability is a receipt line. + The artifact pins are zero placeholders refused at runtime until the tabs land. +- `lcfs_consumption`: `assign_bus_use_incidence` and the fare cells of `rake_to_vendored_facts` + leave the declaration; `price_bus_journeys` (`uk_runtime/bus_fare_pricing.py`) sets + `bus_fare_spending` as Σ over the household's non-eligible persons of trips × k × y per + series, at the chain step as the override (the chain conditions on the raw draw; the support + clip precedes it; every other LCFS column is byte-identical on the fixture). Wales keeps the + clipped raw draw. Gate `uk_stage_lcfs_consumption_bus_pricing` (`bus_pricing`, population fact + check, tolerance 1e-9) recomputes every factor from the vendored rows. +- `etb_services`: the `bus_subsidy_spending` rake stays; gate + `uk_stage_etb_services_support_rake` (`fact_rake`, population fact check) recomputes every + cell's published net support through the stage's own declaration, requires the receipt's + cells and each cell's design-weighted total after the rake to match (Northern Ireland jointly + over bus and rail), and fails closed on a skipped cell; `record_support_per_journey` + (`uk_runtime/bus_support_per_journey.py`) records the value-side alternative, `applied: false`. + +Factors resolved from the vendored rows at FY2024-25 (`fiscal_start: 2024-04-01`; y = receipts +over fare-paying boardings; k = boardings over resident trips, i.e. BUS01 over NTS0705a trips +per resident CY2024 times the ONS mid-2024 population; fare per trip = k × y; C/B = the +publisher's concessionary boarding share): + +- London series (every England resident's bus-in-London trips; BUS05ai London receipts + GBP 1,347.4m; BUS01 1,821.5m boardings; concessionary 497.5m; NTS0705a 13.12 trips per + resident; England 58.62m): k 2.369, y GBP 1.018, fare per trip GBP 2.41, C/B 0.273. +- England outside London (other-local-bus trips of every England resident; receipts + GBP 2,070.0m; 1,850.5m boardings; concessionary 519.1m; 28.07 trips per resident): k 1.125, + y GBP 1.555, fare per trip GBP 1.75, C/B 0.281. +- Scotland (`scotgov.bus.operator_revenue` passenger revenue GBP 391m; 334m journeys; + concessionary 183.6m; England's other-local-bus rate as the declared proxy; population + 5.55m): k 2.145, y GBP 2.600, fare per trip GBP 5.58, C/B 0.550 (the Scottish concession + covers under-22s since 2022, so its boarding share is twice England's; the eligibility rule + matches it). +- Northern Ireland (Translink receipts summed over services GBP 150.1m; 67.8m journeys; DfI + full-fare-concession journeys 8.96m, the 65+ SmartPass series, so half-fare 60–64 boardings + are not deducted, declared; proxy rate; population 1.93m): k 1.253, y GBP 2.551, fare per + trip GBP 3.20, C/B 0.132. +- Wales: unpriced (María's ruling); its imputed trips are receipted, not priced. + +Support components resolved for the diagnostic (England only, where DfT publishes them): +London reimbursement GBP 183.3m over 497.5m concessionary boardings = GBP 0.369 per +concessionary boarding, the rest of the GBP 1,130.2m net support = GBP 0.520 per boarding; +England outside London reimbursement GBP 630.6m over 519.1m = GBP 1.215, the rest of +GBP 1,894.7m net support = GBP 0.683 per boarding. The frame-side numbers (eligible boardings, +value-side support over raked support) wait on the tabs. + +Derived surfaces: the H2 fixture regenerated with synthetic NTS tabs (`_nts_donors()`; 30 +stages; oracle identity on this machine `8a95b3a9c766af1f88cc127d0bc9b5ee38d69528a8b0eeb056adb6e8ec803828`, +unchanged by C6 and C7 because the pricing override leaves the fixture's other columns alone and +the support diagnostic is receipt-only); the release-input coverage manifest (145 required +inputs); the gate battery (53 gates, four new); the gate-battery and certification-part digests +re-pinned in `microcosm-data` after every `gates.json` edit; `tools/ci_test_groups.py --verify` +ok. Export surface gains `household.household_local_bus_trips`. + +## Part E — licensed measurement (pending María's NTS SN 5340 download) + +Not run. In order once the tabs are at `data/ukds/nts_2002_24/`: pin the three artifacts in +`sources.yaml`; spine-t with the #791 twin recipe (`build_791.sh`, the three tabs added) under +`data/ukds/acceptance/930-nts-bus/spine-t/`; the stage gates and their receipts (band shares vs +NTS0313, trips per person by series, quintile and age vs NTS0705a/NTS0303/NTS0601, vehicle +shares vs NTS0205, the eligible trip share beside C/B, frame-implied boardings vs BUS01, the +design-weight fares by target cell against the #904 targets without a rake, the ONS 07.3.2 upper +bound, the support-per-journey reading); the twin diff against spine-s5 under its expectation +(only the new cells and `bus_fare_spending` outside Wales may move); the E6 support bounds for +the new stage; the national calibration round (after #937 or with the round-5 scratch +register) and the Part C anatomy per bus row. From 62436b7418ba7759b4aa044b1b771e3da1e15414 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Fri, 18 Sep 2026 19:31:58 +0100 Subject: [PATCH 06/19] Regenerate the derived surfaces on the 7846605 feed after rebasing over #939 (#930) Main's #939 re-pinned the feed to chronicle c5e5bf8 (the HMRC CGT tables); this branch's pin, 78466057, is its descendant, so the rebase keeps the newer pin and regenerates every surface on it over the merged register: the vendored resources (main's two CGT resources now carry the 78466057 identity beside the three bus resources), the national references and membership, the local census and references, the signed compile-parity receipts, the H2 fixture (31 stages: #725's asset-type stage and #930's nts_bus_travel), the release-input coverage manifest and the gate-battery and certification-part digests. The stage-count pins both sides had bumped to the same number move once more (31 graph stages, 33 declared). Co-Authored-By: Claude Fable 5.1 --- docs/uk-chronicle-feed-repin.md | 2 +- experiments/930-nts-bus-journeys-receipts.md | 12 + .../build/uk/hmrc_cgt_asset_type_facts.json | 8 +- .../build/uk/hmrc_cgt_conditioning_facts.json | 8 +- .../build/uk/target_reference_membership.json | 9935 ++++++++++------- .../tests/test_uk_spine_acceptance_receipt.py | 4 + .../src/microcosm/data/contract.py | 2 +- .../parity/uk_spine/sources/fixture.json | 2 +- 8 files changed, 5710 insertions(+), 4263 deletions(-) diff --git a/docs/uk-chronicle-feed-repin.md b/docs/uk-chronicle-feed-repin.md index 6c43f12ec..0b02d3599 100644 --- a/docs/uk-chronicle-feed-repin.md +++ b/docs/uk-chronicle-feed-repin.md @@ -71,4 +71,4 @@ for England, Wales and Scotland (266,390 rows); the `ec20085` re-pin (#890 PR-S, The `c5e5bf8` re-pin (microcosm#725, chronicle #273, on top of `ec20085`) then brought the HMRC CGT Tables 7, 8 and 9 (asset type, residential property, carried interest), 276,205 rows, with no compiled value moving on either surface. -for England, Wales and Scotland (266,390 rows); the `ec20085` re-pin (#890 PR-S, chronicle #269/#270 via PR #271) brought the domestic energy facts the energy stage levels and prices against (DESNZ Energy Trends domestic consumption, subnational consumption and meter counts, QEP average prices paid, NEED 2024, ONS 04.5 sub-classes) and the census central-heating tables (275,698 rows). The `7846605` re-pin (microcosm#930, chronicle #274 via PR #275) brought the DfT BUS01 passenger and concessionary journeys by area, the BUS05i operating-revenue and support components, the NTS0303/NTS0601 trip rates by mode and age and the DfI full-fare concession journeys (277,183 rows), with the NTS0705a selection pinned to its quintile groupby because the new packages reuse the trip-rate concepts. +The `7846605` re-pin (microcosm#930, chronicle #274 via PR #275, on top of `c5e5bf8`) brought the DfT BUS01 passenger and concessionary journeys by area, the BUS05i operating-revenue and support components, the NTS0303/NTS0601 trip rates by mode and age and the DfI full-fare concession journeys (277,183 rows), with the NTS0705a selection pinned to its quintile groupby because the new packages reuse the trip-rate concepts. diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 144bc5a67..a8f56b2fb 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -55,6 +55,18 @@ Vendored resources (`tools/vendor_uk_ledger_facts.py`, `--check` clean on the pi DfT labels fiscal years by the closing year, so every FY2024-25 selection here is by `fiscal_start: 2024-04-01`, never by label. +Rebase over #939 (2026-09-18, main `ce76b358`): #939 had re-pinned the feed to chronicle `c5e5bf8` +(the HMRC CGT Tables 7–9) with its own regeneration; `78466057` is that commit's descendant on +chronicle main, so the rebase keeps this branch's pin and regenerates every surface on it over +the merged register (commit "Regenerate the derived surfaces on the 7846605 feed after rebasing +over #939"): main's two CGT resources (`hmrc_cgt_conditioning_facts.json` 254 rows, +`hmrc_cgt_asset_type_facts.json` 60) now carry the `78466057` identity beside the three bus +resources; `tools/vendor_uk_ledger_facts.py --check` clean; the national `target_references.json` +is byte-identical to main's (no compiled value moved); the H2 fixture has 31 stages (#725's +`hmrc_cgt_asset_type_spine` and #930's `nts_bus_travel`; oracle identity on this machine +`a57881b2…`), 33 declared; the coverage manifest (145 required) and the gate and part digests +re-pinned; the stage-count pins both sides had bumped to the same number moved once more. + ## Part B — Vahid's third pass on PR #927 (C0, commit `5326ab68`) All nine items closed, none of which changed a value: the stale "FY2024-25 Ofgem pricing set diff --git a/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_asset_type_facts.json b/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_asset_type_facts.json index 74f3eec91..dabe8cd3f 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_asset_type_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_asset_type_facts.json @@ -15,12 +15,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_conditioning_facts.json b/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_conditioning_facts.json index acb45a606..fb1986e83 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_conditioning_facts.json +++ b/packages/microcosm-build/src/microcosm/build/uk/hmrc_cgt_conditioning_facts.json @@ -16,12 +16,12 @@ }, "source_fact_feed": { "source_repo": "PolicyEngine/chronicle", - "source_commit": "c5e5bf8aa84960c1a200ee47303b19c953092d0f", + "source_commit": "78466057401af48f9a53da41b87295241e4af1ba", "build": "build-bundle --suite uk -> build-consumer-artifact", "artifact_schema_version": "policyengine_ledger.consumer_artifact.v2", - "fact_row_count": 276205, - "facts_sha256": "6d039dd869dc1704b0c98fd1d2db72965b1c38de92c165fe4e12c3f530951e2d", - "manifest_sha256": "20ac5d22e7d8f3cdb83dbd7fd617e37e290f5c4c480097057f959aa14033391d" + "fact_row_count": 277183, + "facts_sha256": "8dc4336d776533d0c878d008311f81f936568d6471ee82f025dc8c996ad8867a", + "manifest_sha256": "0ff28c71e7d3c6b61ad776ff223aaad32aa01c8bb832e9834b8969a232ad77d2" }, "selections": [ { diff --git a/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json b/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json index f92a0f9ac..7efaa6dad 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json +++ b/packages/microcosm-build/src/microcosm/build/uk/target_reference_membership.json @@ -1,13 +1,13 @@ { "source_fact_feed": "chronicle-uk-78466057-consumer-facts", "target_period": 2025, - "candidate_count": 646, - "contract_target_count": 247, - "active_reference_count": 631, + "candidate_count": 725, + "contract_target_count": 256, + "active_reference_count": 705, "status_counts": { - "active": 631, + "active": 705, "no_fact_at_or_before_period": 7, - "signed_excluded": 8 + "signed_excluded": 13 }, "geography_pins": { "obr.income_tax": { @@ -2095,6 +2095,138 @@ "dwp.benefit_cap.capped_households_1300_01_and_above": { "geography_level": "country", "geography_id": "K03000001" + }, + "hmrc.cgt.taxpayers_by_age_band": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.gains_by_age_band": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.tax_by_age_band": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.taxpayers_by_region": { + "geography_fanout": [ + { + "geography_level": "region", + "geography_id": "E12000001" + }, + { + "geography_level": "region", + "geography_id": "E12000002" + }, + { + "geography_level": "region", + "geography_id": "E12000003" + }, + { + "geography_level": "region", + "geography_id": "E12000004" + }, + { + "geography_level": "region", + "geography_id": "E12000005" + }, + { + "geography_level": "region", + "geography_id": "E12000006" + }, + { + "geography_level": "region", + "geography_id": "E12000007" + }, + { + "geography_level": "region", + "geography_id": "E12000008" + }, + { + "geography_level": "region", + "geography_id": "E12000009" + }, + { + "geography_level": "country", + "geography_id": "W92000004" + }, + { + "geography_level": "country", + "geography_id": "S92000003" + }, + { + "geography_level": "country", + "geography_id": "N92000002" + } + ] + }, + "hmrc.cgt.gains_by_region": { + "geography_fanout": [ + { + "geography_level": "region", + "geography_id": "E12000001" + }, + { + "geography_level": "region", + "geography_id": "E12000002" + }, + { + "geography_level": "region", + "geography_id": "E12000003" + }, + { + "geography_level": "region", + "geography_id": "E12000004" + }, + { + "geography_level": "region", + "geography_id": "E12000005" + }, + { + "geography_level": "region", + "geography_id": "E12000006" + }, + { + "geography_level": "region", + "geography_id": "E12000007" + }, + { + "geography_level": "region", + "geography_id": "E12000008" + }, + { + "geography_level": "region", + "geography_id": "E12000009" + }, + { + "geography_level": "country", + "geography_id": "W92000004" + }, + { + "geography_level": "country", + "geography_id": "S92000003" + }, + { + "geography_level": "country", + "geography_id": "N92000002" + } + ] + }, + "hmrc.cgt.taxpayers_by_gain_band": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.gains_by_gain_band": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.residential_property_taxpayers": { + "geography_level": "country", + "geography_id": "K02000001" + }, + "hmrc.cgt.residential_property_gains": { + "geography_level": "country", + "geography_id": "K02000001" } }, "genuine_sum_residue": [ @@ -5040,125 +5172,495 @@ "name": "dwp.benefit_cap.capped_households_1300_01_and_above", "from": "2025-11", "to": "2025" - } - ], - "targets": { - "obr.income_tax": { - "status": "active", - "candidates": [ - { - "name": "obr.income_tax", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 331437583074.4429, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_d928e7da0fbfe088ca1a30d7" - } - ] }, - "obr.ni": { - "status": "active", - "candidates": [ - { - "name": "obr.ni", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 200081395082.7125, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_eccab3ee763d68bb782276a7" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_16_to_24", + "from": "2024", + "to": "2025" }, - "obr.ni_employee": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_employee", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 49544363784.26465, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_7e3e3e637a9134760a0a530a" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_25_to_34", + "from": "2024", + "to": "2025" }, - "obr.ni_employer": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_employer", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 145324007512.71753, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8719021c501d9757e0e0814" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_35_to_44", + "from": "2024", + "to": "2025" }, - "obr.ni_self_employed": { - "status": "active", - "candidates": [ - { - "name": "obr.ni_self_employed", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 2902816090.4147716, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b94b7d74d7df7ff5f9309f3b" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_45_to_54", + "from": "2024", + "to": "2025" }, - "obr.vat": { - "status": "active", - "candidates": [ - { - "name": "obr.vat", - "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "resolved_period": 2025, - "resolved_value": 180168938685.41794, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c534c3e6313150f8081b777" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_55_to_64", + "from": "2024", + "to": "2025" }, - "obr.fuel_duties": { - "status": "signed_excluded", - "candidates": [ - { - "name": "obr.fuel_duties", - "status": "signed_excluded", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, - "signed_rationale": "The OBR fuel duties fact is all-road-users receipts (freight, vans, business mileage) against a household frame; obr.fuel_duties_cars binds the cars receipts from the OBR vehicle-type release instead (ruling 2026-09-10). The all-road-users row is retained in the contract for registry parity and signed out here rather than carried as a calibration measure exclusion." - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_65_to_74", + "from": "2024", + "to": "2025" }, - "hmrc.cgt.liability_total": { - "status": "active", - "candidates": [ - { - "name": "hmrc.cgt.liability_total", - "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, - "resolved_period": 2025, - "resolved_value": 22503000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_222c397017de7bff0a6583a7" - } - ] + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_75_to_84", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_85_plus", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_16_to_24", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_25_to_34", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_35_to_44", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_45_to_54", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_55_to_64", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_65_to_74", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_75_to_84", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_85_plus", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_16_to_24", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_25_to_34", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_35_to_44", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_45_to_54", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_55_to_64", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_65_to_74", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_75_to_84", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_85_plus", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000001", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000002", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000003", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000004", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000005", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000006", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000007", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000008", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000009", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@W92000004", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@S92000003", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@N92000002", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000001", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000002", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000003", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000004", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000005", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000006", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000007", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000008", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@E12000009", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@W92000004", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@S92000003", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.gains_by_region@N92000002", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_1000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_100000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_10000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_12300", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_2000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_250000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_25000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_3000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_5000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_500000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_50000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/cgt_taxpayers_band_6000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_1000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_100000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_10000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_12300", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_2000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_250000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_25000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_3000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_5000000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_500000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_50000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc/capital_gains_band_6000", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.residential_property_taxpayers.ty2024", + "from": "2024", + "to": "2025" + }, + { + "name": "hmrc.cgt.residential_property_gains.ty2024", + "from": "2024", + "to": "2025" + } + ], + "targets": { + "obr.income_tax": { + "status": "active", + "candidates": [ + { + "name": "obr.income_tax", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 331437583074.4429, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_d928e7da0fbfe088ca1a30d7" + } + ] + }, + "obr.ni": { + "status": "active", + "candidates": [ + { + "name": "obr.ni", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 200081395082.7125, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_eccab3ee763d68bb782276a7" + } + ] + }, + "obr.ni_employee": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_employee", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 49544363784.26465, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_7e3e3e637a9134760a0a530a" + } + ] + }, + "obr.ni_employer": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_employer", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 145324007512.71753, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_c8719021c501d9757e0e0814" + } + ] + }, + "obr.ni_self_employed": { + "status": "active", + "candidates": [ + { + "name": "obr.ni_self_employed", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 2902816090.4147716, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b94b7d74d7df7ff5f9309f3b" + } + ] + }, + "obr.vat": { + "status": "active", + "candidates": [ + { + "name": "obr.vat", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 180168938685.41794, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_3c534c3e6313150f8081b777" + } + ] + }, + "obr.fuel_duties": { + "status": "signed_excluded", + "candidates": [ + { + "name": "obr.fuel_duties", + "status": "signed_excluded", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "signed_rationale": "The OBR fuel duties fact is all-road-users receipts (freight, vans, business mileage) against a household frame; obr.fuel_duties_cars binds the cars receipts from the OBR vehicle-type release instead (ruling 2026-09-10). The all-road-users row is retained in the contract for registry parity and signed out here rather than carried as a calibration measure exclusion." + } + ] + }, + "hmrc.cgt.liability_total": { + "status": "active", + "candidates": [ + { + "name": "hmrc.cgt.liability_total", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 22503000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_222c397017de7bff0a6583a7" + } + ] }, "obr.sdlt": { "status": "active", @@ -5224,7880 +5726,8768 @@ "status": "active", "candidates": [ { - "name": "obr.council_tax", + "name": "obr.council_tax", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 50925163826.30539, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_16bcd3e2a16bfa44c0b1ea74" + } + ] + }, + "obr.council_tax_england": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "obr.council_tax_england", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.council_tax_scotland": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "obr.council_tax_scotland", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.council_tax_wales": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "obr.council_tax_wales", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.domestic_rates": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "obr.domestic_rates", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "obr.esa": { + "status": "active", + "candidates": [ + { + "name": "obr.esa", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 7206287181.538654, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_632a67850494984d9b35e639" + } + ] + }, + "obr.housing_benefit": { + "status": "active", + "candidates": [ + { + "name": "obr.housing_benefit", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 12103254163.788864, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_984cc88cfc4242bd80c679f3" + } + ] + }, + "obr.jobseekers_allowance": { + "status": "active", + "candidates": [ + { + "name": "obr.jobseekers_allowance", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 280558748.04472804, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_d505f8a08a29411dcf69287b" + } + ] + }, + "obr.pension_credit": { + "status": "active", + "candidates": [ + { + "name": "obr.pension_credit", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 6146422389.476461, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_95ea9bc008361c26f90591d4" + } + ] + }, + "obr.pip": { + "status": "active", + "candidates": [ + { + "name": "obr.pip", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 36910059270.5278, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_548ebadeb7d774b32fa6f4ff" + } + ] + }, + "obr.state_pension": { + "status": "active", + "candidates": [ + { + "name": "obr.state_pension", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 146185954351.57382, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_567e55f9f73df2808c1c4be8" + } + ] + }, + "obr.statutory_maternity_pay": { + "status": "active", + "candidates": [ + { + "name": "obr.statutory_maternity_pay", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 3194800881.520547, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_0c45b526e2b233b22d955cc6" + } + ] + }, + "obr.tv_licence_fee": { + "status": "active", + "candidates": [ + { + "name": "obr.tv_licence_fee", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 3872000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b0f0afcd44c93532837c9f2a" + } + ] + }, + "obr.universal_credit_in_cap": { + "status": "active", + "candidates": [ + { + "name": "obr.universal_credit_in_cap", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 66410800011.47837, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" + } + ] + }, + "obr.universal_credit_outside_cap": { + "status": "active", + "candidates": [ + { + "name": "obr.universal_credit_outside_cap", + "status": "active", + "matched_fact_count_overall": 7, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 12875549128.065746, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4c927d7b33d1eee2455bdbd0" + } + ] + }, + "obr.winter_fuel_allowance": { + "status": "active", + "candidates": [ + { + "name": "obr.winter_fuel_allowance", "status": "active", "matched_fact_count_overall": 7, "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 50925163826.30539, + "resolved_value": 1911040880.4619167, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_16bcd3e2a16bfa44c0b1ea74" + "resolved_fact_key": "ledger_aggregate_fact_v2_575778670363b5890c8de847" } ] }, - "obr.council_tax_england": { - "status": "no_fact_at_or_before_period", + "isc.private_school_students": { + "status": "active", "candidates": [ { - "name": "obr.council_tax_england", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + "name": "isc.private_school_students", + "status": "active", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, + "resolved_period": 2025, + "resolved_value": 556551.0, + "resolved_fact_period": "2024-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_67bd24e7f9158af756625865" } ] }, - "obr.council_tax_scotland": { - "status": "no_fact_at_or_before_period", + "hmrc.salary_sacrifice.it_relief_basic_rate": { + "status": "active", "candidates": [ { - "name": "obr.council_tax_scotland", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + "name": "hmrc.salary_sacrifice.it_relief_basic_rate", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 1600000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7320889e57785e6997224191" } ] }, - "obr.council_tax_wales": { - "status": "no_fact_at_or_before_period", + "hmrc.salary_sacrifice.it_relief_higher_rate": { + "status": "active", "candidates": [ { - "name": "obr.council_tax_wales", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + "name": "hmrc.salary_sacrifice.it_relief_higher_rate", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 5500000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7d9ff26814151157071301e9" } ] }, - "obr.domestic_rates": { - "status": "no_fact_at_or_before_period", + "hmrc.salary_sacrifice.it_relief_additional_rate": { + "status": "active", "candidates": [ { - "name": "obr.domestic_rates", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + "name": "hmrc.salary_sacrifice.it_relief_additional_rate", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 1800000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_49a712ba4b22f0b4b2925ef9" } ] }, - "obr.esa": { + "hmrc.salary_sacrifice.nics_relief_employee": { "status": "active", "candidates": [ { - "name": "obr.esa", + "name": "hmrc.salary_sacrifice.nics_relief_employee", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7206287181.538654, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_632a67850494984d9b35e639" + "resolved_value": 1000000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_341767859ef6030c06c7a153" } ] }, - "obr.housing_benefit": { + "hmrc.salary_sacrifice.nics_relief_employer": { "status": "active", "candidates": [ { - "name": "obr.housing_benefit", + "name": "hmrc.salary_sacrifice.nics_relief_employer", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12103254163.788864, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_984cc88cfc4242bd80c679f3" + "resolved_value": 3400000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_026ae1169f5f0f997bb06479" } ] }, - "obr.jobseekers_allowance": { + "hmrc.salary_sacrifice.users_total": { "status": "active", "candidates": [ { - "name": "obr.jobseekers_allowance", + "name": "hmrc.salary_sacrifice.users_total", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 280558748.04472804, + "resolved_value": 7700000.0, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_d505f8a08a29411dcf69287b" + "resolved_fact_key": "ledger_aggregate_fact_v2_06d585b8684b5fe0ce25f6ec" } ] }, - "obr.pension_credit": { + "hmrc.salary_sacrifice.users_below_cap": { "status": "active", "candidates": [ { - "name": "obr.pension_credit", + "name": "hmrc.salary_sacrifice.users_below_cap", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6146422389.476461, + "resolved_value": 4300000.0, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_95ea9bc008361c26f90591d4" + "resolved_fact_key": "ledger_aggregate_fact_v2_a48e584180a6f33d07112d3c" } ] }, - "obr.pip": { + "hmrc.salary_sacrifice.users_above_cap": { "status": "active", "candidates": [ { - "name": "obr.pip", + "name": "hmrc.salary_sacrifice.users_above_cap", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 36910059270.5278, + "resolved_value": 3300000.0, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_548ebadeb7d774b32fa6f4ff" + "resolved_fact_key": "ledger_aggregate_fact_v2_0331d77688891a3c3c3307b6" } ] }, - "obr.state_pension": { + "hmrc.spi.employment_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "obr.state_pension", + "name": "hmrc/employment_income_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 82300000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_b1c634a871c843888ab00545" + }, + { + "name": "hmrc/employment_income_income_band_1_000_000_to_inf", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 35500000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_16019afa59e224b690877826" + }, + { + "name": "hmrc/employment_income_income_band_12_570_to_15_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 16900000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_a82c84f67b40867564d2c847" + }, + { + "name": "hmrc/employment_income_income_band_15_000_to_20_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 48600000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_42eb325b6a29afb3e6d157fa" + }, + { + "name": "hmrc/employment_income_income_band_150_000_to_200_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 39200000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1f93702eb88f381f0701c4f8" + }, + { + "name": "hmrc/employment_income_income_band_20_000_to_30_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 172000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_794fd9633d6a2018fee633e7" + }, + { + "name": "hmrc/employment_income_income_band_200_000_to_300_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 36600000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d85ad655daaa164b1ab33231" + }, + { + "name": "hmrc/employment_income_income_band_30_000_to_40_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 170000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3607635c72d16b4059b6a3f6" + }, + { + "name": "hmrc/employment_income_income_band_300_000_to_500_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 29000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_5c3674b48269ffe3c7b28a1b" + }, + { + "name": "hmrc/employment_income_income_band_40_000_to_50_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 139000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_525aeb02ab9a831608756200" + }, + { + "name": "hmrc/employment_income_income_band_50_000_to_70_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 174000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_9f1a70b4e0995af34d7dbbfb" + }, + { + "name": "hmrc/employment_income_income_band_500_000_to_1_000_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 146185954351.57382, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_567e55f9f73df2808c1c4be8" - } - ] - }, - "obr.statutory_maternity_pay": { - "status": "active", - "candidates": [ + "resolved_value": 23100000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1944a2f33309b41b2d5f348d" + }, { - "name": "obr.statutory_maternity_pay", + "name": "hmrc/employment_income_income_band_70_000_to_100_000", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3194800881.520547, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_0c45b526e2b233b22d955cc6" + "resolved_value": 118000000000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_6178d003a4c1a6198294f174" } ] }, - "obr.tv_licence_fee": { + "hmrc.spi.employment_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "obr.tv_licence_fee", + "name": "hmrc/employment_income_count_income_band_100_000_to_150_000", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3872000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b0f0afcd44c93532837c9f2a" - } - ] - }, - "obr.universal_credit_in_cap": { - "status": "active", - "candidates": [ + "resolved_value": 791000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_b83fec2e722ef22cbe28ee76" + }, { - "name": "obr.universal_credit_in_cap", + "name": "hmrc/employment_income_count_income_band_1_000_000_to_inf", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 66410800011.47837, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" - } - ] - }, - "obr.universal_credit_outside_cap": { - "status": "active", - "candidates": [ + "resolved_value": 21000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_618b4f84a2b10fdf0d901df6" + }, { - "name": "obr.universal_credit_outside_cap", + "name": "hmrc/employment_income_count_income_band_12_570_to_15_000", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12875549128.065746, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4c927d7b33d1eee2455bdbd0" - } - ] - }, - "obr.winter_fuel_allowance": { - "status": "active", - "candidates": [ + "resolved_value": 1360000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_5a2e006ccd94f8754760661c" + }, { - "name": "obr.winter_fuel_allowance", + "name": "hmrc/employment_income_count_income_band_15_000_to_20_000", "status": "active", - "matched_fact_count_overall": 7, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1911040880.4619167, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_575778670363b5890c8de847" - } - ] - }, - "isc.private_school_students": { - "status": "active", - "candidates": [ + "resolved_value": 3100000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_a4ecaa65aa113092a1c8fcf7" + }, { - "name": "isc.private_school_students", + "name": "hmrc/employment_income_count_income_band_150_000_to_200_000", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 556551.0, - "resolved_fact_period": "2024-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_67bd24e7f9158af756625865" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_basic_rate": { - "status": "active", - "candidates": [ + "resolved_value": 264000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffcb46afae1c469de75ee9b3" + }, { - "name": "hmrc.salary_sacrifice.it_relief_basic_rate", + "name": "hmrc/employment_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1600000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7320889e57785e6997224191" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_higher_rate": { - "status": "active", - "candidates": [ + "resolved_value": 7470000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_1bbafa142b4bfc426ce5bdac" + }, { - "name": "hmrc.salary_sacrifice.it_relief_higher_rate", + "name": "hmrc/employment_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5500000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_7d9ff26814151157071301e9" - } - ] - }, - "hmrc.salary_sacrifice.it_relief_additional_rate": { - "status": "active", - "candidates": [ + "resolved_value": 180000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_dd00b1e66c3254ddc0e108a6" + }, { - "name": "hmrc.salary_sacrifice.it_relief_additional_rate", + "name": "hmrc/employment_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1800000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_49a712ba4b22f0b4b2925ef9" - } - ] - }, - "hmrc.salary_sacrifice.nics_relief_employee": { - "status": "active", - "candidates": [ + "resolved_value": 5370000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3bd51396d03aee4164d7c1d6" + }, { - "name": "hmrc.salary_sacrifice.nics_relief_employee", + "name": "hmrc/employment_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1000000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_341767859ef6030c06c7a153" - } - ] - }, - "hmrc.salary_sacrifice.nics_relief_employer": { - "status": "active", - "candidates": [ + "resolved_value": 93000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_d1f4ceb7f4e676d9ff044d80" + }, { - "name": "hmrc.salary_sacrifice.nics_relief_employer", + "name": "hmrc/employment_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3400000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_026ae1169f5f0f997bb06479" - } - ] - }, - "hmrc.salary_sacrifice.users_total": { - "status": "active", - "candidates": [ + "resolved_value": 3500000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_874b13ae1da1064e73055c39" + }, { - "name": "hmrc.salary_sacrifice.users_total", + "name": "hmrc/employment_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7700000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_06d585b8684b5fe0ce25f6ec" - } - ] - }, - "hmrc.salary_sacrifice.users_below_cap": { - "status": "active", - "candidates": [ + "resolved_value": 3430000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_572104f32689df4a2dc4c334" + }, { - "name": "hmrc.salary_sacrifice.users_below_cap", + "name": "hmrc/employment_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4300000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_a48e584180a6f33d07112d3c" - } - ] - }, - "hmrc.salary_sacrifice.users_above_cap": { - "status": "active", - "candidates": [ + "resolved_value": 44000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_3b99d6944753bf5696bdc8f9" + }, { - "name": "hmrc.salary_sacrifice.users_above_cap", + "name": "hmrc/employment_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3300000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_0331d77688891a3c3c3307b6" + "resolved_value": 1640000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_8eec35d25c57e9c2e2c7962b" } ] }, - "hmrc.spi.employment_income.amount_by_total_income_band": { + "hmrc.spi.self_employment_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/employment_income_income_band_100_000_to_150_000", + "name": "hmrc/self_employment_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 82300000000.0, + "resolved_value": 4980000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b1c634a871c843888ab00545" + "resolved_fact_key": "ledger_aggregate_fact_v2_5b616c7ebeb21ef5305b8beb" }, { - "name": "hmrc/employment_income_income_band_1_000_000_to_inf", + "name": "hmrc/self_employment_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 35500000000.0, + "resolved_value": 19500000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_16019afa59e224b690877826" + "resolved_fact_key": "ledger_aggregate_fact_v2_761827852b6a2fccb3d15132" }, { - "name": "hmrc/employment_income_income_band_12_570_to_15_000", + "name": "hmrc/self_employment_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16900000000.0, + "resolved_value": 4810000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a82c84f67b40867564d2c847" + "resolved_fact_key": "ledger_aggregate_fact_v2_1a69068db718770de7df525e" }, { - "name": "hmrc/employment_income_income_band_15_000_to_20_000", + "name": "hmrc/self_employment_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 48600000000.0, + "resolved_value": 8030000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_42eb325b6a29afb3e6d157fa" + "resolved_fact_key": "ledger_aggregate_fact_v2_c1df7ca022a9c007f122de6d" }, { - "name": "hmrc/employment_income_income_band_150_000_to_200_000", + "name": "hmrc/self_employment_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 39200000000.0, + "resolved_value": 3650000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1f93702eb88f381f0701c4f8" + "resolved_fact_key": "ledger_aggregate_fact_v2_7183b7c143f8e897552ad685" }, { - "name": "hmrc/employment_income_income_band_20_000_to_30_000", + "name": "hmrc/self_employment_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 172000000000.0, + "resolved_value": 15700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_794fd9633d6a2018fee633e7" + "resolved_fact_key": "ledger_aggregate_fact_v2_33c4f0779c40ec91ff6761da" }, { - "name": "hmrc/employment_income_income_band_200_000_to_300_000", + "name": "hmrc/self_employment_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 36600000000.0, + "resolved_value": 4390000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d85ad655daaa164b1ab33231" + "resolved_fact_key": "ledger_aggregate_fact_v2_90652f32ebe0ff36c569998d" }, { - "name": "hmrc/employment_income_income_band_30_000_to_40_000", + "name": "hmrc/self_employment_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 170000000000.0, + "resolved_value": 12600000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3607635c72d16b4059b6a3f6" + "resolved_fact_key": "ledger_aggregate_fact_v2_1b9ad3f39e949b92a26ec28c" }, { - "name": "hmrc/employment_income_income_band_300_000_to_500_000", + "name": "hmrc/self_employment_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 29000000000.0, + "resolved_value": 4840000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5c3674b48269ffe3c7b28a1b" + "resolved_fact_key": "ledger_aggregate_fact_v2_96f921ffdb56a575057076f8" }, { - "name": "hmrc/employment_income_income_band_40_000_to_50_000", + "name": "hmrc/self_employment_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 139000000000.0, + "resolved_value": 8730000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_525aeb02ab9a831608756200" + "resolved_fact_key": "ledger_aggregate_fact_v2_645090db5db62f7c47a34f60" }, { - "name": "hmrc/employment_income_income_band_50_000_to_70_000", + "name": "hmrc/self_employment_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 174000000000.0, + "resolved_value": 8220000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_9f1a70b4e0995af34d7dbbfb" + "resolved_fact_key": "ledger_aggregate_fact_v2_f0d7af3458463a645af3cb76" }, { - "name": "hmrc/employment_income_income_band_500_000_to_1_000_000", + "name": "hmrc/self_employment_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 23100000000.0, + "resolved_value": 6670000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1944a2f33309b41b2d5f348d" + "resolved_fact_key": "ledger_aggregate_fact_v2_fc7a985c6a2a3d69e2c9ae75" }, { - "name": "hmrc/employment_income_income_band_70_000_to_100_000", + "name": "hmrc/self_employment_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 118000000000.0, + "resolved_value": 5360000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6178d003a4c1a6198294f174" + "resolved_fact_key": "ledger_aggregate_fact_v2_c588886840e4e7e4a141ac75" } ] }, - "hmrc.spi.employment_income.count_by_total_income_band": { + "hmrc.spi.self_employment_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/employment_income_count_income_band_100_000_to_150_000", + "name": "hmrc/self_employment_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 791000.0, + "resolved_value": 85000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b83fec2e722ef22cbe28ee76" + "resolved_fact_key": "ledger_aggregate_fact_v2_db16ef55b3b0f60d292b745b" }, { - "name": "hmrc/employment_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/self_employment_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 21000.0, + "resolved_value": 11000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_618b4f84a2b10fdf0d901df6" + "resolved_fact_key": "ledger_aggregate_fact_v2_315a063dab8497ed5b8837b6" }, { - "name": "hmrc/employment_income_count_income_band_12_570_to_15_000", + "name": "hmrc/self_employment_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1360000.0, + "resolved_value": 444000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5a2e006ccd94f8754760661c" + "resolved_fact_key": "ledger_aggregate_fact_v2_498ad10a35b58ff55819bc8b" }, { - "name": "hmrc/employment_income_count_income_band_15_000_to_20_000", + "name": "hmrc/self_employment_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3100000.0, + "resolved_value": 651000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a4ecaa65aa113092a1c8fcf7" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb849a98f57c60bd507d621b" }, { - "name": "hmrc/employment_income_count_income_band_150_000_to_200_000", + "name": "hmrc/self_employment_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 264000.0, + "resolved_value": 40000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffcb46afae1c469de75ee9b3" + "resolved_fact_key": "ledger_aggregate_fact_v2_cfb6ca3c4eff6a83bd5c10ac" }, { - "name": "hmrc/employment_income_count_income_band_20_000_to_30_000", + "name": "hmrc/self_employment_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7470000.0, + "resolved_value": 961000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1bbafa142b4bfc426ce5bdac" + "resolved_fact_key": "ledger_aggregate_fact_v2_72bd71f362434b2260a4b407" }, { - "name": "hmrc/employment_income_count_income_band_200_000_to_300_000", + "name": "hmrc/self_employment_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 180000.0, + "resolved_value": 34000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd00b1e66c3254ddc0e108a6" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe86d957cb9590b3292e1757" }, { - "name": "hmrc/employment_income_count_income_band_30_000_to_40_000", + "name": "hmrc/self_employment_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5370000.0, + "resolved_value": 595000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3bd51396d03aee4164d7c1d6" + "resolved_fact_key": "ledger_aggregate_fact_v2_84b75f0a77e11de0182b9d87" }, { - "name": "hmrc/employment_income_count_income_band_300_000_to_500_000", + "name": "hmrc/self_employment_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 93000.0, + "resolved_value": 21000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d1f4ceb7f4e676d9ff044d80" + "resolved_fact_key": "ledger_aggregate_fact_v2_5c668fd92047d28d73d7c36d" }, { - "name": "hmrc/employment_income_count_income_band_40_000_to_50_000", + "name": "hmrc/self_employment_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3500000.0, + "resolved_value": 359000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_874b13ae1da1064e73055c39" + "resolved_fact_key": "ledger_aggregate_fact_v2_876b5e55461ed15a7456d8b3" }, { - "name": "hmrc/employment_income_count_income_band_50_000_to_70_000", + "name": "hmrc/self_employment_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3430000.0, + "resolved_value": 311000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_572104f32689df4a2dc4c334" + "resolved_fact_key": "ledger_aggregate_fact_v2_09e5a5c61ccf990f6104a903" }, { - "name": "hmrc/employment_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/self_employment_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 44000.0, + "resolved_value": 15000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b99d6944753bf5696bdc8f9" + "resolved_fact_key": "ledger_aggregate_fact_v2_73031eb82b28c872e4371fae" }, { - "name": "hmrc/employment_income_count_income_band_70_000_to_100_000", + "name": "hmrc/self_employment_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1640000.0, + "resolved_value": 143000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8eec35d25c57e9c2e2c7962b" + "resolved_fact_key": "ledger_aggregate_fact_v2_c35c3f72e5f7901457970c8d" } ] }, - "hmrc.spi.self_employment_income.amount_by_total_income_band": { + "hmrc.spi.dividend_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/self_employment_income_income_band_100_000_to_150_000", + "name": "hmrc/dividend_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4980000000.0, + "resolved_value": 6870000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5b616c7ebeb21ef5305b8beb" + "resolved_fact_key": "ledger_aggregate_fact_v2_6fd01f132dc6b218c02326b1" }, { - "name": "hmrc/self_employment_income_income_band_1_000_000_to_inf", + "name": "hmrc/dividend_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 19500000000.0, + "resolved_value": 11100000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_761827852b6a2fccb3d15132" + "resolved_fact_key": "ledger_aggregate_fact_v2_3c0cd54a0f0609d8ebc58a25" }, { - "name": "hmrc/self_employment_income_income_band_12_570_to_15_000", + "name": "hmrc/dividend_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4810000000.0, + "resolved_value": 175000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1a69068db718770de7df525e" + "resolved_fact_key": "ledger_aggregate_fact_v2_b63a84056f85bed14b8ab8fd" }, { - "name": "hmrc/self_employment_income_income_band_15_000_to_20_000", + "name": "hmrc/dividend_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8030000000.0, + "resolved_value": 855000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c1df7ca022a9c007f122de6d" + "resolved_fact_key": "ledger_aggregate_fact_v2_3c4f22fc63944665033b18b3" }, { - "name": "hmrc/self_employment_income_income_band_150_000_to_200_000", + "name": "hmrc/dividend_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3650000000.0, + "resolved_value": 3450000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7183b7c143f8e897552ad685" + "resolved_fact_key": "ledger_aggregate_fact_v2_ced1a5840ced099b471d4e84" }, { - "name": "hmrc/self_employment_income_income_band_20_000_to_30_000", + "name": "hmrc/dividend_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 15700000000.0, + "resolved_value": 3330000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_33c4f0779c40ec91ff6761da" + "resolved_fact_key": "ledger_aggregate_fact_v2_8a115e840b38a6603d618bc0" }, { - "name": "hmrc/self_employment_income_income_band_200_000_to_300_000", + "name": "hmrc/dividend_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4390000000.0, + "resolved_value": 3700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_90652f32ebe0ff36c569998d" + "resolved_fact_key": "ledger_aggregate_fact_v2_0394e55216df7f3dcab84fb5" }, { - "name": "hmrc/self_employment_income_income_band_30_000_to_40_000", + "name": "hmrc/dividend_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12600000000.0, + "resolved_value": 4700000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1b9ad3f39e949b92a26ec28c" + "resolved_fact_key": "ledger_aggregate_fact_v2_ea93d59adaf66ef73e9dddbf" }, { - "name": "hmrc/self_employment_income_income_band_300_000_to_500_000", + "name": "hmrc/dividend_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4840000000.0, + "resolved_value": 3430000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f921ffdb56a575057076f8" + "resolved_fact_key": "ledger_aggregate_fact_v2_8d09d2287cbdb2e4f4004521" }, { - "name": "hmrc/self_employment_income_income_band_40_000_to_50_000", + "name": "hmrc/dividend_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8730000000.0, + "resolved_value": 8400000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_645090db5db62f7c47a34f60" + "resolved_fact_key": "ledger_aggregate_fact_v2_0a4329a3eb027a530c6f02ec" }, { - "name": "hmrc/self_employment_income_income_band_50_000_to_70_000", + "name": "hmrc/dividend_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8220000000.0, + "resolved_value": 12500000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0d7af3458463a645af3cb76" + "resolved_fact_key": "ledger_aggregate_fact_v2_c11497ffe45250b909593f1d" }, { - "name": "hmrc/self_employment_income_income_band_500_000_to_1_000_000", + "name": "hmrc/dividend_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6670000000.0, + "resolved_value": 3820000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc7a985c6a2a3d69e2c9ae75" + "resolved_fact_key": "ledger_aggregate_fact_v2_dafc8ca1cd03e5d461b11d4e" }, { - "name": "hmrc/self_employment_income_income_band_70_000_to_100_000", + "name": "hmrc/dividend_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5360000000.0, + "resolved_value": 9440000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c588886840e4e7e4a141ac75" + "resolved_fact_key": "ledger_aggregate_fact_v2_940e6ce9db10080ed5613faa" } ] }, - "hmrc.spi.self_employment_income.count_by_total_income_band": { + "hmrc.spi.dividend_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/self_employment_income_count_income_band_100_000_to_150_000", + "name": "hmrc/dividend_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 85000.0, + "resolved_value": 222000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_db16ef55b3b0f60d292b745b" + "resolved_fact_key": "ledger_aggregate_fact_v2_35b535ef60b7e9e8ddad45af" }, { - "name": "hmrc/self_employment_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/dividend_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11000.0, + "resolved_value": 19000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_315a063dab8497ed5b8837b6" + "resolved_fact_key": "ledger_aggregate_fact_v2_fbe097b0ffbcc0e7a301478d" }, { - "name": "hmrc/self_employment_income_count_income_band_12_570_to_15_000", + "name": "hmrc/dividend_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 444000.0, + "resolved_value": 115000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_498ad10a35b58ff55819bc8b" + "resolved_fact_key": "ledger_aggregate_fact_v2_3a657db84b033007853ec14b" }, { - "name": "hmrc/self_employment_income_count_income_band_15_000_to_20_000", + "name": "hmrc/dividend_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 651000.0, + "resolved_value": 372000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb849a98f57c60bd507d621b" + "resolved_fact_key": "ledger_aggregate_fact_v2_418541677821ff087753a7b4" }, { - "name": "hmrc/self_employment_income_count_income_band_150_000_to_200_000", + "name": "hmrc/dividend_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 40000.0, + "resolved_value": 92000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_cfb6ca3c4eff6a83bd5c10ac" + "resolved_fact_key": "ledger_aggregate_fact_v2_426db10645b611899a770dbd" }, { - "name": "hmrc/self_employment_income_count_income_band_20_000_to_30_000", + "name": "hmrc/dividend_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 961000.0, + "resolved_value": 843000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_72bd71f362434b2260a4b407" + "resolved_fact_key": "ledger_aggregate_fact_v2_937f405149e37c0c900a62ee" }, { - "name": "hmrc/self_employment_income_count_income_band_200_000_to_300_000", + "name": "hmrc/dividend_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 34000.0, + "resolved_value": 75000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe86d957cb9590b3292e1757" + "resolved_fact_key": "ledger_aggregate_fact_v2_6c0e32c82b968ba545457cab" }, { - "name": "hmrc/self_employment_income_count_income_band_30_000_to_40_000", + "name": "hmrc/dividend_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 595000.0, + "resolved_value": 667000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_84b75f0a77e11de0182b9d87" + "resolved_fact_key": "ledger_aggregate_fact_v2_c8fc2a8e3993c51b68cc6f8a" }, { - "name": "hmrc/self_employment_income_count_income_band_300_000_to_500_000", + "name": "hmrc/dividend_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 21000.0, + "resolved_value": 49000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5c668fd92047d28d73d7c36d" + "resolved_fact_key": "ledger_aggregate_fact_v2_439d9908bf6880e33103ea7d" }, { - "name": "hmrc/self_employment_income_count_income_band_40_000_to_50_000", + "name": "hmrc/dividend_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 359000.0, + "resolved_value": 627000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_876b5e55461ed15a7456d8b3" + "resolved_fact_key": "ledger_aggregate_fact_v2_60bb54980a6ca69ff77d07f0" }, { - "name": "hmrc/self_employment_income_count_income_band_50_000_to_70_000", + "name": "hmrc/dividend_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 311000.0, + "resolved_value": 643000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_09e5a5c61ccf990f6104a903" + "resolved_fact_key": "ledger_aggregate_fact_v2_56b8b1dd7aec08c3abddc3a0" }, { - "name": "hmrc/self_employment_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/dividend_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 15000.0, + "resolved_value": 32000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73031eb82b28c872e4371fae" + "resolved_fact_key": "ledger_aggregate_fact_v2_c9f024b8595617fc8dd8e416" }, { - "name": "hmrc/self_employment_income_count_income_band_70_000_to_100_000", + "name": "hmrc/dividend_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 143000.0, + "resolved_value": 336000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c35c3f72e5f7901457970c8d" + "resolved_fact_key": "ledger_aggregate_fact_v2_2ed13533e012fdd1fec68a67" } ] }, - "hmrc.spi.dividend_income.amount_by_total_income_band": { + "hmrc.spi.property_income.amount_by_total_income_band": { + "status": "signed_excluded", + "candidates": [ + { + "name": "hmrc.spi.property_income.amount_by_total_income_band", + "status": "signed_excluded", + "matched_fact_count_overall": 13, + "matched_fact_count_at_or_before_period": 13, + "signed_rationale": "Signed out pending a first-class value-scaling operation or a Chronicle package for HMRC Property Rental Income Statistics with declared reconciliation: the Ledger facts are official HMRC SPI Table 3.7 net property-income amounts, while the incumbent calibration target applies the populace-side x1.9 property-income undercount adjustment. The x1.9 trace is uk-data PR #311 / issue uk-data#230: SPI covers only taxpayers with liability, and HMRC Property Rental Income Statistics show GBP 46.68bn versus SPI about GBP 24.5bn for 2020-21. Binding the raw SPI facts would knowingly calibrate to 10/19 of the incumbent surface." + } + ] + }, + "hmrc.spi.property_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/dividend_income_income_band_100_000_to_150_000", + "name": "hmrc/property_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6870000000.0, + "resolved_value": 137000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6fd01f132dc6b218c02326b1" + "resolved_fact_key": "ledger_aggregate_fact_v2_50e02eb85969a4773af5cade" }, { - "name": "hmrc/dividend_income_income_band_1_000_000_to_inf", + "name": "hmrc/property_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 11100000000.0, + "resolved_value": 7000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c0cd54a0f0609d8ebc58a25" + "resolved_fact_key": "ledger_aggregate_fact_v2_d286366fea43c9f897936709" }, { - "name": "hmrc/dividend_income_income_band_12_570_to_15_000", + "name": "hmrc/property_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 175000000.0, + "resolved_value": 101000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b63a84056f85bed14b8ab8fd" + "resolved_fact_key": "ledger_aggregate_fact_v2_80d817cee2f3592809f3a194" }, { - "name": "hmrc/dividend_income_income_band_15_000_to_20_000", + "name": "hmrc/property_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 855000000.0, + "resolved_value": 232000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3c4f22fc63944665033b18b3" + "resolved_fact_key": "ledger_aggregate_fact_v2_2c0d78b9f9dff4e5fdfa250c" }, { - "name": "hmrc/dividend_income_income_band_150_000_to_200_000", + "name": "hmrc/property_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3450000000.0, + "resolved_value": 54000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ced1a5840ced099b471d4e84" + "resolved_fact_key": "ledger_aggregate_fact_v2_5ec672db73bb4f35958a409e" }, { - "name": "hmrc/dividend_income_income_band_20_000_to_30_000", + "name": "hmrc/property_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3330000000.0, + "resolved_value": 431000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8a115e840b38a6603d618bc0" + "resolved_fact_key": "ledger_aggregate_fact_v2_3eb40c70c3de0d0c29253566" }, { - "name": "hmrc/dividend_income_income_band_200_000_to_300_000", + "name": "hmrc/property_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3700000000.0, + "resolved_value": 41000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0394e55216df7f3dcab84fb5" + "resolved_fact_key": "ledger_aggregate_fact_v2_0394669c5734865fda5f0541" }, { - "name": "hmrc/dividend_income_income_band_30_000_to_40_000", + "name": "hmrc/property_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4700000000.0, + "resolved_value": 364000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ea93d59adaf66ef73e9dddbf" + "resolved_fact_key": "ledger_aggregate_fact_v2_6564bb4b662365729676a9e1" }, { - "name": "hmrc/dividend_income_income_band_300_000_to_500_000", + "name": "hmrc/property_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3430000000.0, + "resolved_value": 23000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8d09d2287cbdb2e4f4004521" + "resolved_fact_key": "ledger_aggregate_fact_v2_87c457b7ee2392ee8360893b" }, { - "name": "hmrc/dividend_income_income_band_40_000_to_50_000", + "name": "hmrc/property_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8400000000.0, + "resolved_value": 325000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a4329a3eb027a530c6f02ec" + "resolved_fact_key": "ledger_aggregate_fact_v2_7187a98d8342886b08e3f9e2" }, { - "name": "hmrc/dividend_income_income_band_50_000_to_70_000", + "name": "hmrc/property_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12500000000.0, + "resolved_value": 397000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c11497ffe45250b909593f1d" + "resolved_fact_key": "ledger_aggregate_fact_v2_c44a33c3bc4454de20132027" }, { - "name": "hmrc/dividend_income_income_band_500_000_to_1_000_000", + "name": "hmrc/property_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3820000000.0, + "resolved_value": 13000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_dafc8ca1cd03e5d461b11d4e" + "resolved_fact_key": "ledger_aggregate_fact_v2_831e0c70ca80d37c785d4122" }, { - "name": "hmrc/dividend_income_income_band_70_000_to_100_000", + "name": "hmrc/property_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9440000000.0, + "resolved_value": 226000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_940e6ce9db10080ed5613faa" + "resolved_fact_key": "ledger_aggregate_fact_v2_f93d04a399cee892e5ec86b6" } ] }, - "hmrc.spi.dividend_income.count_by_total_income_band": { + "hmrc.spi.private_pension_income.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/dividend_income_count_income_band_100_000_to_150_000", + "name": "hmrc/private_pension_income_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 222000.0, + "resolved_value": 5430000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_35b535ef60b7e9e8ddad45af" + "resolved_fact_key": "ledger_aggregate_fact_v2_cb943439ee9edfb445bc3fa5" }, { - "name": "hmrc/dividend_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/private_pension_income_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 19000.0, + "resolved_value": 370000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbe097b0ffbcc0e7a301478d" + "resolved_fact_key": "ledger_aggregate_fact_v2_7dcf8568040de10d9b3765da" }, { - "name": "hmrc/dividend_income_count_income_band_12_570_to_15_000", + "name": "hmrc/private_pension_income_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 115000.0, + "resolved_value": 4350000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3a657db84b033007853ec14b" + "resolved_fact_key": "ledger_aggregate_fact_v2_699889c2fb48479e27e44a4a" }, { - "name": "hmrc/dividend_income_count_income_band_15_000_to_20_000", + "name": "hmrc/private_pension_income_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 372000.0, + "resolved_value": 13600000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_418541677821ff087753a7b4" + "resolved_fact_key": "ledger_aggregate_fact_v2_0f977d0b50c1d0f1d1364e88" }, { - "name": "hmrc/dividend_income_count_income_band_150_000_to_200_000", + "name": "hmrc/private_pension_income_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 92000.0, + "resolved_value": 1810000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_426db10645b611899a770dbd" + "resolved_fact_key": "ledger_aggregate_fact_v2_d29aac0680380c80bd842bae" }, { - "name": "hmrc/dividend_income_count_income_band_20_000_to_30_000", + "name": "hmrc/private_pension_income_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 843000.0, + "resolved_value": 30200000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_937f405149e37c0c900a62ee" + "resolved_fact_key": "ledger_aggregate_fact_v2_bafcebe21a05cb0ca19d5e4f" }, { - "name": "hmrc/dividend_income_count_income_band_200_000_to_300_000", + "name": "hmrc/private_pension_income_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 75000.0, + "resolved_value": 1570000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6c0e32c82b968ba545457cab" + "resolved_fact_key": "ledger_aggregate_fact_v2_de0ed091681463c4ddec5b85" }, { - "name": "hmrc/dividend_income_count_income_band_30_000_to_40_000", + "name": "hmrc/private_pension_income_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 667000.0, + "resolved_value": 24900000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8fc2a8e3993c51b68cc6f8a" + "resolved_fact_key": "ledger_aggregate_fact_v2_2884a006a8d7c144a8570a7d" }, { - "name": "hmrc/dividend_income_count_income_band_300_000_to_500_000", + "name": "hmrc/private_pension_income_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 49000.0, + "resolved_value": 1120000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_439d9908bf6880e33103ea7d" + "resolved_fact_key": "ledger_aggregate_fact_v2_73e8de3b1ac198cc75c2b696" }, { - "name": "hmrc/dividend_income_count_income_band_40_000_to_50_000", + "name": "hmrc/private_pension_income_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 627000.0, + "resolved_value": 16900000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_60bb54980a6ca69ff77d07f0" + "resolved_fact_key": "ledger_aggregate_fact_v2_6b29cd5a1d665a00bb3e8046" }, { - "name": "hmrc/dividend_income_count_income_band_50_000_to_70_000", + "name": "hmrc/private_pension_income_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 643000.0, + "resolved_value": 17400000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_56b8b1dd7aec08c3abddc3a0" + "resolved_fact_key": "ledger_aggregate_fact_v2_8f911d955de4f80e87dc69d8" }, { - "name": "hmrc/dividend_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/private_pension_income_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 32000.0, + "resolved_value": 640000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c9f024b8595617fc8dd8e416" + "resolved_fact_key": "ledger_aggregate_fact_v2_a13e6165bec82537c5c2883c" }, { - "name": "hmrc/dividend_income_count_income_band_70_000_to_100_000", + "name": "hmrc/private_pension_income_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 336000.0, + "resolved_value": 9470000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ed13533e012fdd1fec68a67" - } - ] - }, - "hmrc.spi.property_income.amount_by_total_income_band": { - "status": "signed_excluded", - "candidates": [ - { - "name": "hmrc.spi.property_income.amount_by_total_income_band", - "status": "signed_excluded", - "matched_fact_count_overall": 13, - "matched_fact_count_at_or_before_period": 13, - "signed_rationale": "Signed out pending a first-class value-scaling operation or a Chronicle package for HMRC Property Rental Income Statistics with declared reconciliation: the Ledger facts are official HMRC SPI Table 3.7 net property-income amounts, while the incumbent calibration target applies the populace-side x1.9 property-income undercount adjustment. The x1.9 trace is uk-data PR #311 / issue uk-data#230: SPI covers only taxpayers with liability, and HMRC Property Rental Income Statistics show GBP 46.68bn versus SPI about GBP 24.5bn for 2020-21. Binding the raw SPI facts would knowingly calibrate to 10/19 of the incumbent surface." + "resolved_fact_key": "ledger_aggregate_fact_v2_0a1db235b87cad00eeddbfd8" } ] }, - "hmrc.spi.property_income.count_by_total_income_band": { + "hmrc.spi.private_pension_income.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/property_income_count_income_band_100_000_to_150_000", + "name": "hmrc/private_pension_income_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 137000.0, + "resolved_value": 109000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_50e02eb85969a4773af5cade" + "resolved_fact_key": "ledger_aggregate_fact_v2_1fa1ba97628c6c2c315f0e15" }, { - "name": "hmrc/property_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/private_pension_income_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7000.0, + "resolved_value": 2000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d286366fea43c9f897936709" + "resolved_fact_key": "ledger_aggregate_fact_v2_188f8f1a0535263e4db7c9a8" }, { - "name": "hmrc/property_income_count_income_band_12_570_to_15_000", + "name": "hmrc/private_pension_income_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 101000.0, + "resolved_value": 1070000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_80d817cee2f3592809f3a194" + "resolved_fact_key": "ledger_aggregate_fact_v2_853f104082cf479b98952c1a" }, { - "name": "hmrc/property_income_count_income_band_15_000_to_20_000", + "name": "hmrc/private_pension_income_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 232000.0, + "resolved_value": 2140000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2c0d78b9f9dff4e5fdfa250c" + "resolved_fact_key": "ledger_aggregate_fact_v2_c785199ee1d08fabfe927ff0" }, { - "name": "hmrc/property_income_count_income_band_150_000_to_200_000", + "name": "hmrc/private_pension_income_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 54000.0, + "resolved_value": 29000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_5ec672db73bb4f35958a409e" + "resolved_fact_key": "ledger_aggregate_fact_v2_a98ec830dee0eceb16b452e7" }, { - "name": "hmrc/property_income_count_income_band_20_000_to_30_000", + "name": "hmrc/private_pension_income_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 431000.0, + "resolved_value": 2660000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3eb40c70c3de0d0c29253566" + "resolved_fact_key": "ledger_aggregate_fact_v2_1df6f17a33011c1c026dbc09" }, { - "name": "hmrc/property_income_count_income_band_200_000_to_300_000", + "name": "hmrc/private_pension_income_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 41000.0, + "resolved_value": 20000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0394669c5734865fda5f0541" + "resolved_fact_key": "ledger_aggregate_fact_v2_042ab8896eb0214e7bbad477" }, { - "name": "hmrc/property_income_count_income_band_30_000_to_40_000", + "name": "hmrc/private_pension_income_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 364000.0, + "resolved_value": 1450000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6564bb4b662365729676a9e1" + "resolved_fact_key": "ledger_aggregate_fact_v2_0a28fd76533fc93cf8dbfe4a" }, { - "name": "hmrc/property_income_count_income_band_300_000_to_500_000", + "name": "hmrc/private_pension_income_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 23000.0, + "resolved_value": 10000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_87c457b7ee2392ee8360893b" + "resolved_fact_key": "ledger_aggregate_fact_v2_7fccfc3ee4246841b3ed391b" }, { - "name": "hmrc/property_income_count_income_band_40_000_to_50_000", + "name": "hmrc/private_pension_income_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 325000.0, + "resolved_value": 779000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7187a98d8342886b08e3f9e2" + "resolved_fact_key": "ledger_aggregate_fact_v2_0f808aa135a13e5aa4668d22" }, { - "name": "hmrc/property_income_count_income_band_50_000_to_70_000", + "name": "hmrc/private_pension_income_count_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 397000.0, + "resolved_value": 643000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c44a33c3bc4454de20132027" + "resolved_fact_key": "ledger_aggregate_fact_v2_097efdacf2adf0f90f90d1de" }, { - "name": "hmrc/property_income_count_income_band_500_000_to_1_000_000", + "name": "hmrc/private_pension_income_count_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13000.0, + "resolved_value": 4000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_831e0c70ca80d37c785d4122" + "resolved_fact_key": "ledger_aggregate_fact_v2_8abdd0aa368c3d693e6d0989" }, { - "name": "hmrc/property_income_count_income_band_70_000_to_100_000", + "name": "hmrc/private_pension_income_count_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 226000.0, + "resolved_value": 259000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f93d04a399cee892e5ec86b6" + "resolved_fact_key": "ledger_aggregate_fact_v2_f75fc4c3e2cb06bbdb7543f8" } ] }, - "hmrc.spi.private_pension_income.amount_by_total_income_band": { + "hmrc.spi.state_pension.amount_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/private_pension_income_income_band_100_000_to_150_000", + "name": "hmrc/state_pension_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5430000000.0, + "resolved_value": 847000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_cb943439ee9edfb445bc3fa5" + "resolved_fact_key": "ledger_aggregate_fact_v2_d63e1a96cab57582f482b8c2" }, { - "name": "hmrc/private_pension_income_income_band_1_000_000_to_inf", + "name": "hmrc/state_pension_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 370000000.0, + "resolved_value": 20000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7dcf8568040de10d9b3765da" + "resolved_fact_key": "ledger_aggregate_fact_v2_9a20bd62d4d5984865242929" }, { - "name": "hmrc/private_pension_income_income_band_12_570_to_15_000", + "name": "hmrc/state_pension_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4350000000.0, + "resolved_value": 11800000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_699889c2fb48479e27e44a4a" + "resolved_fact_key": "ledger_aggregate_fact_v2_45083c1383ea711226aebd1b" }, { - "name": "hmrc/private_pension_income_income_band_15_000_to_20_000", + "name": "hmrc/state_pension_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13600000000.0, + "resolved_value": 22200000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0f977d0b50c1d0f1d1364e88" + "resolved_fact_key": "ledger_aggregate_fact_v2_310febb949c686fad2b71a94" }, { - "name": "hmrc/private_pension_income_income_band_150_000_to_200_000", + "name": "hmrc/state_pension_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1810000000.0, + "resolved_value": 265000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d29aac0680380c80bd842bae" + "resolved_fact_key": "ledger_aggregate_fact_v2_e79668076aadc063559585e9" }, { - "name": "hmrc/private_pension_income_income_band_20_000_to_30_000", + "name": "hmrc/state_pension_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 30200000000.0, + "resolved_value": 24900000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_bafcebe21a05cb0ca19d5e4f" + "resolved_fact_key": "ledger_aggregate_fact_v2_3d18e138c32f6581d6dafdd7" }, { - "name": "hmrc/private_pension_income_income_band_200_000_to_300_000", + "name": "hmrc/state_pension_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1570000000.0, + "resolved_value": 179000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_de0ed091681463c4ddec5b85" + "resolved_fact_key": "ledger_aggregate_fact_v2_e1dda799099ac0f4f439700d" }, { - "name": "hmrc/private_pension_income_income_band_30_000_to_40_000", + "name": "hmrc/state_pension_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 24900000000.0, + "resolved_value": 12300000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2884a006a8d7c144a8570a7d" + "resolved_fact_key": "ledger_aggregate_fact_v2_151045b793ac454ab29260fc" }, { - "name": "hmrc/private_pension_income_income_band_300_000_to_500_000", + "name": "hmrc/state_pension_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1120000000.0, + "resolved_value": 96000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73e8de3b1ac198cc75c2b696" + "resolved_fact_key": "ledger_aggregate_fact_v2_c95154893499181b7f3a8903" }, { - "name": "hmrc/private_pension_income_income_band_40_000_to_50_000", + "name": "hmrc/state_pension_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16900000000.0, + "resolved_value": 6020000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_6b29cd5a1d665a00bb3e8046" + "resolved_fact_key": "ledger_aggregate_fact_v2_bc4cee7d39f5e1c311464a55" }, { - "name": "hmrc/private_pension_income_income_band_50_000_to_70_000", + "name": "hmrc/state_pension_income_band_50_000_to_70_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 17400000000.0, + "resolved_value": 4660000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8f911d955de4f80e87dc69d8" + "resolved_fact_key": "ledger_aggregate_fact_v2_7f09c940c0fbc3cc42b9e510" }, { - "name": "hmrc/private_pension_income_income_band_500_000_to_1_000_000", + "name": "hmrc/state_pension_income_band_500_000_to_1_000_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 640000000.0, + "resolved_value": 43000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a13e6165bec82537c5c2883c" + "resolved_fact_key": "ledger_aggregate_fact_v2_d265dfcd4ba09d10053a78a4" }, { - "name": "hmrc/private_pension_income_income_band_70_000_to_100_000", + "name": "hmrc/state_pension_income_band_70_000_to_100_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9470000000.0, + "resolved_value": 1890000000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a1db235b87cad00eeddbfd8" + "resolved_fact_key": "ledger_aggregate_fact_v2_41c1df25454fdf413d5765d7" } ] }, - "hmrc.spi.private_pension_income.count_by_total_income_band": { + "hmrc.spi.state_pension.count_by_total_income_band": { "status": "active", "candidates": [ { - "name": "hmrc/private_pension_income_count_income_band_100_000_to_150_000", + "name": "hmrc/state_pension_count_income_band_100_000_to_150_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 109000.0, + "resolved_value": 74000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1fa1ba97628c6c2c315f0e15" + "resolved_fact_key": "ledger_aggregate_fact_v2_01b8f391c006c09d3ed51865" }, { - "name": "hmrc/private_pension_income_count_income_band_1_000_000_to_inf", + "name": "hmrc/state_pension_count_income_band_1_000_000_to_inf", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, "resolved_value": 2000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_188f8f1a0535263e4db7c9a8" + "resolved_fact_key": "ledger_aggregate_fact_v2_b8c359bb976d919bedb9076a" }, { - "name": "hmrc/private_pension_income_count_income_band_12_570_to_15_000", + "name": "hmrc/state_pension_count_income_band_12_570_to_15_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1070000.0, + "resolved_value": 1140000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_853f104082cf479b98952c1a" + "resolved_fact_key": "ledger_aggregate_fact_v2_05f2cd00648c7f8225723a9c" }, { - "name": "hmrc/private_pension_income_count_income_band_15_000_to_20_000", + "name": "hmrc/state_pension_count_income_band_15_000_to_20_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2140000.0, + "resolved_value": 2050000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c785199ee1d08fabfe927ff0" + "resolved_fact_key": "ledger_aggregate_fact_v2_ced75bd10fbfa56ef2eabeae" }, { - "name": "hmrc/private_pension_income_count_income_band_150_000_to_200_000", + "name": "hmrc/state_pension_count_income_band_150_000_to_200_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 29000.0, + "resolved_value": 21000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_a98ec830dee0eceb16b452e7" + "resolved_fact_key": "ledger_aggregate_fact_v2_73d438db1a168d794e290b0e" }, { - "name": "hmrc/private_pension_income_count_income_band_20_000_to_30_000", + "name": "hmrc/state_pension_count_income_band_20_000_to_30_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2660000.0, + "resolved_value": 2320000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1df6f17a33011c1c026dbc09" + "resolved_fact_key": "ledger_aggregate_fact_v2_69b521bf537da156d2afa48e" }, { - "name": "hmrc/private_pension_income_count_income_band_200_000_to_300_000", + "name": "hmrc/state_pension_count_income_band_200_000_to_300_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 20000.0, + "resolved_value": 14000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_042ab8896eb0214e7bbad477" + "resolved_fact_key": "ledger_aggregate_fact_v2_3edcf70605856bb8b906ea19" }, { - "name": "hmrc/private_pension_income_count_income_band_30_000_to_40_000", + "name": "hmrc/state_pension_count_income_band_30_000_to_40_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1450000.0, + "resolved_value": 1160000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0a28fd76533fc93cf8dbfe4a" + "resolved_fact_key": "ledger_aggregate_fact_v2_1cafb0f484a7d8191b7fb989" }, { - "name": "hmrc/private_pension_income_count_income_band_300_000_to_500_000", + "name": "hmrc/state_pension_count_income_band_300_000_to_500_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 10000.0, + "resolved_value": 8000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7fccfc3ee4246841b3ed391b" + "resolved_fact_key": "ledger_aggregate_fact_v2_7f510c873457703c57c16983" }, { - "name": "hmrc/private_pension_income_count_income_band_40_000_to_50_000", + "name": "hmrc/state_pension_count_income_band_40_000_to_50_000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 779000.0, + "resolved_value": 568000.0, "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_0f808aa135a13e5aa4668d22" + "resolved_fact_key": "ledger_aggregate_fact_v2_d4ff6839b2d936396ae33f67" + }, + { + "name": "hmrc/state_pension_count_income_band_50_000_to_70_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 441000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_2b5023baae0b6814c07afbe9" + }, + { + "name": "hmrc/state_pension_count_income_band_500_000_to_1_000_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 3000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9a834c26fa7c215c052f4f5" }, { - "name": "hmrc/private_pension_income_count_income_band_50_000_to_70_000", + "name": "hmrc/state_pension_count_income_band_70_000_to_100_000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 176000.0, + "resolved_fact_period": "2023", + "resolved_fact_key": "ledger_aggregate_fact_v2_7514fbdbf5f909008b617d06" + } + ] + }, + "hmrc.cgt.taxpayers_total": { + "status": "active", + "candidates": [ + { + "name": "hmrc.cgt.taxpayers_total", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 551000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_31d709fc393c2bf4d04efca5" + } + ] + }, + "hmrc.cgt.gains_total": { + "status": "active", + "candidates": [ + { + "name": "hmrc.cgt.gains_total", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 119258000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_12060d20a417d85d67cf24e8" + } + ] + }, + "dwp.benefit_cap.capped_households": { + "status": "active", + "candidates": [ + { + "name": "dwp.benefit_cap.capped_households", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 643000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_097efdacf2adf0f90f90d1de" - }, + "resolved_value": 110637.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_b698397897ed849f096cdd94" + } + ] + }, + "dwp.pip.daily_living_standard_claimants": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "hmrc/private_pension_income_count_income_band_500_000_to_1_000_000", + "name": "dwp.pip.daily_living_standard_claimants", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "dwp.pip.daily_living_enhanced_claimants": { + "status": "no_fact_at_or_before_period", + "candidates": [ + { + "name": "dwp.pip.daily_living_enhanced_claimants", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "dwp.esa_claimants": { + "status": "active", + "candidates": [ + { + "name": "dwp.esa_claimants", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_8abdd0aa368c3d693e6d0989" - }, + "resolved_value": 1000000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_16ef67af9274891abd5e4fdc" + } + ] + }, + "dwp.esa_contrib_claimants": { + "status": "active", + "candidates": [ { - "name": "hmrc/private_pension_income_count_income_band_70_000_to_100_000", + "name": "dwp.esa_contrib_claimants", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 259000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f75fc4c3e2cb06bbdb7543f8" + "resolved_value": 620000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_bf22883b03cf631864b2ae1d" } ] }, - "hmrc.spi.state_pension.amount_by_total_income_band": { + "dwp.esa_income_claimants": { "status": "active", "candidates": [ { - "name": "hmrc/state_pension_income_band_100_000_to_150_000", + "name": "dwp.esa_income_claimants", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 847000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d63e1a96cab57582f482b8c2" - }, + "resolved_value": 180000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_8684f0c35a1d71a291e61c81" + } + ] + }, + "dwp.jsa_claimants": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_1_000_000_to_inf", + "name": "dwp.jsa_claimants", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 20000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_9a20bd62d4d5984865242929" - }, + "resolved_value": 71000.0, + "resolved_fact_period": "2025-08", + "resolved_fact_key": "ledger_aggregate_fact_v2_b5d92ff094ad2c534847291a" + } + ] + }, + "dwp.uc.households_children_1": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_12_570_to_15_000", + "name": "dwp.uc.households_children_1", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 11800000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_45083c1383ea711226aebd1b" - }, + "resolved_value": 1190123.8333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_c1533879baf52aaa88758083" + } + ] + }, + "dwp.uc.households_children_2": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_15_000_to_20_000", + "name": "dwp.uc.households_children_2", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 22200000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_310febb949c686fad2b71a94" - }, + "resolved_value": 1049895.5, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_46fca4f9d4e0519f0c190824" + } + ] + }, + "dwp.uc.households_children_3": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_150_000_to_200_000", + "name": "dwp.uc.households_children_3", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 265000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_e79668076aadc063559585e9" - }, + "resolved_value": 477887.6666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ba5bce203605d4e16037d311" + } + ] + }, + "dwp.uc.households_children_4": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_20_000_to_30_000", + "name": "dwp.uc.households_children_4", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 24900000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d18e138c32f6581d6dafdd7" - }, + "resolved_value": 170713.66666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_33541aafa05a63dcae4fc144" + } + ] + }, + "dwp.uc.households_children_5_or_more": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_200_000_to_300_000", + "name": "dwp.uc.households_children_5_or_more", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 179000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_e1dda799099ac0f4f439700d" - }, + "resolved_value": 76320.08333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_33d99593d166153ca2d0adec" + } + ] + }, + "dwp.uc.households_single_no_children": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_30_000_to_40_000", + "name": "dwp.uc.households_single_no_children", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 12300000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_151045b793ac454ab29260fc" - }, + "resolved_value": 2990070.1666666665, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_c013630f1154eb7252466457" + } + ] + }, + "dwp.uc.households_single_with_children": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_300_000_to_500_000", + "name": "dwp.uc.households_single_with_children", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 96000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_c95154893499181b7f3a8903" - }, + "resolved_value": 2138780.1666666665, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_4e21ff5e364647d7c75589d2" + } + ] + }, + "dwp.uc.households_couple_no_children": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_40_000_to_50_000", + "name": "dwp.uc.households_couple_no_children", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, + "resolved_period": 2025, + "resolved_value": 241130.91666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ad46a5483afd6bad20dc50fe" + } + ] + }, + "dwp.uc.households_couple_with_children": { + "status": "active", + "candidates": [ + { + "name": "dwp.uc.households_couple_with_children", + "status": "active", + "matched_fact_count_overall": 24, + "matched_fact_count_at_or_before_period": 24, + "matched_fact_count_in_source_window": 24, "resolved_period": 2025, - "resolved_value": 6020000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_bc4cee7d39f5e1c311464a55" - }, + "resolved_value": 826160.8333333334, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_1a76243d3f616b19eaed3e0a" + } + ] + }, + "dwp.uc.payment_distribution_single": { + "status": "active", + "candidates": [ { - "name": "hmrc/state_pension_income_band_50_000_to_70_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_0_to_1_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 4660000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7f09c940c0fbc3cc42b9e510" + "resolved_value": 89479.33333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_2ab0a2ad4fff5a73eb430af0" }, { - "name": "hmrc/state_pension_income_band_500_000_to_1_000_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_1_200_to_2_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 43000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d265dfcd4ba09d10053a78a4" + "resolved_value": 127403.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_4da96f3f87204e3b63a7197e" }, { - "name": "hmrc/state_pension_income_band_70_000_to_100_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_12_000_to_13_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1890000000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_41c1df25454fdf413d5765d7" - } - ] - }, - "hmrc.spi.state_pension.count_by_total_income_band": { - "status": "active", - "candidates": [ + "resolved_value": 122035.55555555556, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_100f173ee4233f5ed3616bbc" + }, { - "name": "hmrc/state_pension_count_income_band_100_000_to_150_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_13_200_to_14_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 74000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_01b8f391c006c09d3ed51865" + "resolved_value": 197163.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_263205affbfb94c0a87b7834" }, { - "name": "hmrc/state_pension_count_income_band_1_000_000_to_inf", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_14_400_to_15_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8c359bb976d919bedb9076a" + "resolved_value": 209497.33333333334, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f4e51bd6399c4a72f10e625f" }, { - "name": "hmrc/state_pension_count_income_band_12_570_to_15_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_15_600_to_16_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1140000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_05f2cd00648c7f8225723a9c" + "resolved_value": 149963.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_746aa1e8d116c4543251b137" }, { - "name": "hmrc/state_pension_count_income_band_15_000_to_20_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_16_800_to_18_000", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2050000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_ced75bd10fbfa56ef2eabeae" + "resolved_value": 108689.66666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_0dc82a9ba1ce7a8ea1855991" }, { - "name": "hmrc/state_pension_count_income_band_150_000_to_200_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_18_000_to_19_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 21000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_73d438db1a168d794e290b0e" + "resolved_value": 61718.666666666664, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_4399ab26a944d2d46a12311d" }, { - "name": "hmrc/state_pension_count_income_band_20_000_to_30_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_19_200_to_20_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2320000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_69b521bf537da156d2afa48e" + "resolved_value": 34050.444444444445, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_b8ab0a63fbef46e02aa34d37" }, { - "name": "hmrc/state_pension_count_income_band_200_000_to_300_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_20_400_to_21_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 14000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_3edcf70605856bb8b906ea19" + "resolved_value": 22338.333333333332, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_d22d996cd3edb838030ab0dc" }, { - "name": "hmrc/state_pension_count_income_band_30_000_to_40_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_21_600_to_22_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1160000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_1cafb0f484a7d8191b7fb989" + "resolved_value": 14685.777777777777, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_404ce9f1ea3e17ec602a1de9" }, { - "name": "hmrc/state_pension_count_income_band_300_000_to_500_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_22_800_to_24_000", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 8000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7f510c873457703c57c16983" + "resolved_value": 11133.666666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_d2268373d3e5894e10f3f004" }, { - "name": "hmrc/state_pension_count_income_band_40_000_to_50_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 568000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_d4ff6839b2d936396ae33f67" + "resolved_value": 197136.66666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_37e9e071fb187dab220f3876" }, { - "name": "hmrc/state_pension_count_income_band_50_000_to_70_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_24_000_to_25_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 441000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_2b5023baae0b6814c07afbe9" + "resolved_value": 6951.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8af773c191130cd03d9de884" }, { - "name": "hmrc/state_pension_count_income_band_500_000_to_1_000_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_25_200_to_26_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 3000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9a834c26fa7c215c052f4f5" + "resolved_value": 6508.222222222223, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f46b09c321cf98f8e0d12b89" }, { - "name": "hmrc/state_pension_count_income_band_70_000_to_100_000", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_26_400_to_27_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 176000.0, - "resolved_fact_period": "2023", - "resolved_fact_key": "ledger_aggregate_fact_v2_7514fbdbf5f909008b617d06" - } - ] - }, - "hmrc.cgt.taxpayers_total": { - "status": "active", - "candidates": [ + "resolved_value": 5913.444444444444, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_a763ca2d87febd61de26d8b0" + }, { - "name": "hmrc.cgt.taxpayers_total", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_27_600_to_28_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 551000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_31d709fc393c2bf4d04efca5" - } - ] - }, - "hmrc.cgt.gains_total": { - "status": "active", - "candidates": [ + "resolved_value": 1884.111111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8b6d8894debcbda5e38c0923" + }, { - "name": "hmrc.cgt.gains_total", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_28_800_to_30_000", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 119258000000.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_12060d20a417d85d67cf24e8" - } - ] - }, - "dwp.benefit_cap.capped_households": { - "status": "active", - "candidates": [ + "resolved_value": 1653.7777777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_aa3077a36f37ae73562e57fc" + }, { - "name": "dwp.benefit_cap.capped_households", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_3_600_to_4_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 110637.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_b698397897ed849f096cdd94" - } - ] - }, - "dwp.pip.daily_living_standard_claimants": { - "status": "no_fact_at_or_before_period", - "candidates": [ - { - "name": "dwp.pip.daily_living_standard_claimants", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "dwp.pip.daily_living_enhanced_claimants": { - "status": "no_fact_at_or_before_period", - "candidates": [ + "resolved_value": 377063.1111111111, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_988e854b9584a36b1b62810f" + }, { - "name": "dwp.pip.daily_living_enhanced_claimants", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "dwp.esa_claimants": { - "status": "active", - "candidates": [ + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_4_800_to_6_000", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 195983.22222222222, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7a3e7c9563c15ba28ffd3c3e" + }, { - "name": "dwp.esa_claimants", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_6_000_to_7_200", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1000000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_16ef67af9274891abd5e4fdc" - } - ] - }, - "dwp.esa_contrib_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 114033.33333333333, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_294fdb23cc02a98334267137" + }, { - "name": "dwp.esa_contrib_claimants", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_7_200_to_8_400", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 620000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_bf22883b03cf631864b2ae1d" - } - ] - }, - "dwp.esa_income_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 149043.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_5d4a92d292c96a2f440dee5a" + }, { - "name": "dwp.esa_income_claimants", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_8_400_to_9_600", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 180000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_8684f0c35a1d71a291e61c81" - } - ] - }, - "dwp.jsa_claimants": { - "status": "active", - "candidates": [ + "resolved_value": 399750.22222222225, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ad92f85c0ac85ea7bb6e8ca3" + }, { - "name": "dwp.jsa_claimants", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_9_600_to_10_800", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 71000.0, - "resolved_fact_period": "2025-08", - "resolved_fact_key": "ledger_aggregate_fact_v2_b5d92ff094ad2c534847291a" - } - ] - }, - "dwp.uc.households_children_1": { - "status": "active", - "candidates": [ + "resolved_value": 386411.6666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_e2bbf1fe386cfcd8db712026" + }, { - "name": "dwp.uc.households_children_1", + "name": "dwp/uc_payment_dist/SINGLE_annual_payment_10_800_to_12_000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1190123.8333333333, + "resolved_value": 104891.11111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c1533879baf52aaa88758083" + "resolved_fact_key": "ledger_aggregate_fact_v2_de2719af6e4d5f9ffe65aaee" } ] }, - "dwp.uc.households_children_2": { + "dwp.uc.payment_distribution_lone_parent": { "status": "active", "candidates": [ { - "name": "dwp.uc.households_children_2", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_0_to_1_200", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1049895.5, + "resolved_value": 26670.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_46fca4f9d4e0519f0c190824" - } - ] - }, - "dwp.uc.households_children_3": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_7b17c88cf49645b2d3ef44a6" + }, { - "name": "dwp.uc.households_children_3", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_1_200_to_2_400", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 477887.6666666667, + "resolved_value": 36208.11111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba5bce203605d4e16037d311" - } - ] - }, - "dwp.uc.households_children_4": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_765ace417ceafd524ffda4c0" + }, { - "name": "dwp.uc.households_children_4", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_12_000_to_13_200", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 170713.66666666666, + "resolved_value": 125798.44444444444, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_33541aafa05a63dcae4fc144" - } - ] - }, - "dwp.uc.households_children_5_or_more": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_eaddee052a3861f259b93272" + }, { - "name": "dwp.uc.households_children_5_or_more", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_13_200_to_14_400", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 76320.08333333333, + "resolved_value": 129133.66666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_33d99593d166153ca2d0adec" - } - ] - }, - "dwp.uc.households_single_no_children": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_b8d66013c8a68e423f507be8" + }, { - "name": "dwp.uc.households_single_no_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_14_400_to_15_600", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2990070.1666666665, + "resolved_value": 115856.66666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c013630f1154eb7252466457" - } - ] - }, - "dwp.uc.households_single_with_children": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_1bc84efe74c485d143caab7b" + }, { - "name": "dwp.uc.households_single_with_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_15_600_to_16_800", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2138780.1666666665, + "resolved_value": 125660.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4e21ff5e364647d7c75589d2" - } - ] - }, - "dwp.uc.households_couple_no_children": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e26d2d7e425a94fd9fde3d17" + }, + { + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_16_800_to_18_000", + "status": "active", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, + "resolved_period": 2025, + "resolved_value": 135836.77777777778, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_8fa2e062c33297530d458054" + }, { - "name": "dwp.uc.households_couple_no_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_18_000_to_19_200", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 241130.91666666666, + "resolved_value": 135444.88888888888, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad46a5483afd6bad20dc50fe" - } - ] - }, - "dwp.uc.households_couple_with_children": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_77cb72042ffb9b2b1af769e3" + }, { - "name": "dwp.uc.households_couple_with_children", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_19_200_to_20_400", "status": "active", - "matched_fact_count_overall": 24, - "matched_fact_count_at_or_before_period": 24, - "matched_fact_count_in_source_window": 24, + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 826160.8333333334, + "resolved_value": 106341.88888888889, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1a76243d3f616b19eaed3e0a" - } - ] - }, - "dwp.uc.payment_distribution_single": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_acb89a96425fd7af119e0c3b" + }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_0_to_1_200", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_20_400_to_21_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 89479.33333333333, + "resolved_value": 85490.44444444444, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ab0a2ad4fff5a73eb430af0" + "resolved_fact_key": "ledger_aggregate_fact_v2_3aa5825f5e5e8dbc570c0af1" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_1_200_to_2_400", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_21_600_to_22_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 127403.22222222222, + "resolved_value": 80226.88888888889, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4da96f3f87204e3b63a7197e" + "resolved_fact_key": "ledger_aggregate_fact_v2_c5a0ee450c3ad7f882dfb167" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_12_000_to_13_200", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_22_800_to_24_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 122035.55555555556, + "resolved_value": 71259.55555555556, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_100f173ee4233f5ed3616bbc" + "resolved_fact_key": "ledger_aggregate_fact_v2_13ffca0d11c038fc7d096ec9" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_13_200_to_14_400", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_2_400_to_3_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 197163.22222222222, + "resolved_value": 46312.77777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_263205affbfb94c0a87b7834" + "resolved_fact_key": "ledger_aggregate_fact_v2_6619e26753d01d76247e1759" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_14_400_to_15_600", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_24_000_to_25_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 209497.33333333334, + "resolved_value": 51301.666666666664, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f4e51bd6399c4a72f10e625f" + "resolved_fact_key": "ledger_aggregate_fact_v2_4a935006e5c346bfe0009055" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_15_600_to_16_800", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_25_200_to_26_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 149963.22222222222, + "resolved_value": 43305.22222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_746aa1e8d116c4543251b137" + "resolved_fact_key": "ledger_aggregate_fact_v2_e64560bd9c14d083cd03c985" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_16_800_to_18_000", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_26_400_to_27_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 108689.66666666667, + "resolved_value": 34910.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0dc82a9ba1ce7a8ea1855991" + "resolved_fact_key": "ledger_aggregate_fact_v2_8e16d0c97924701eb074c25d" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_18_000_to_19_200", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_27_600_to_28_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 61718.666666666664, + "resolved_value": 28513.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4399ab26a944d2d46a12311d" + "resolved_fact_key": "ledger_aggregate_fact_v2_cf9757018b0d313f20342b59" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_19_200_to_20_400", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_28_800_to_30_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 34050.444444444445, + "resolved_value": 22593.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8ab0a63fbef46e02aa34d37" + "resolved_fact_key": "ledger_aggregate_fact_v2_6bede883f015e48e86c0a2de" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_20_400_to_21_600", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_3_600_to_4_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 22338.333333333332, + "resolved_value": 60310.11111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d22d996cd3edb838030ab0dc" + "resolved_fact_key": "ledger_aggregate_fact_v2_b0710535c8b6006db118eb3b" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_21_600_to_22_800", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_4_800_to_6_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 14685.777777777777, + "resolved_value": 67858.66666666667, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_404ce9f1ea3e17ec602a1de9" + "resolved_fact_key": "ledger_aggregate_fact_v2_b4008c8b22190b4ee185d4f6" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_22_800_to_24_000", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_6_000_to_7_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 11133.666666666666, + "resolved_value": 89577.44444444444, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d2268373d3e5894e10f3f004" + "resolved_fact_key": "ledger_aggregate_fact_v2_1d1fadffae053bf60d7fcd7e" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_2_400_to_3_600", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_7_200_to_8_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 197136.66666666666, + "resolved_value": 116076.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_37e9e071fb187dab220f3876" + "resolved_fact_key": "ledger_aggregate_fact_v2_fae65610a14d6c22f475d757" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_24_000_to_25_200", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_8_400_to_9_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 6951.222222222223, + "resolved_value": 97511.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8af773c191130cd03d9de884" + "resolved_fact_key": "ledger_aggregate_fact_v2_540c0869e23edc4a402166bf" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_25_200_to_26_400", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_9_600_to_10_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 6508.222222222223, + "resolved_value": 102343.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f46b09c321cf98f8e0d12b89" + "resolved_fact_key": "ledger_aggregate_fact_v2_a170bf444a17ae88a80766b0" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_26_400_to_27_600", + "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_10_800_to_12_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 5913.444444444444, + "resolved_value": 123718.11111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a763ca2d87febd61de26d8b0" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b7d0d6add859217e797a66ea" + } + ] + }, + "dwp.uc.payment_distribution_couple_no_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_27_600_to_28_800", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_0_to_1_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1884.111111111111, + "resolved_value": 7506.333333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8b6d8894debcbda5e38c0923" + "resolved_fact_key": "ledger_aggregate_fact_v2_e8af6f4ef9d70ded4a4bf6b5" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_28_800_to_30_000", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_1_200_to_2_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1653.7777777777778, + "resolved_value": 8797.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_aa3077a36f37ae73562e57fc" + "resolved_fact_key": "ledger_aggregate_fact_v2_28514ff922f7b00a4706e74b" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_3_600_to_4_800", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_12_000_to_13_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 377063.1111111111, + "resolved_value": 16121.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_988e854b9584a36b1b62810f" + "resolved_fact_key": "ledger_aggregate_fact_v2_8b8e20276b7af9f670009f64" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_4_800_to_6_000", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_13_200_to_14_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 195983.22222222222, + "resolved_value": 13317.333333333334, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7a3e7c9563c15ba28ffd3c3e" + "resolved_fact_key": "ledger_aggregate_fact_v2_22e83b92481a8b2267a15309" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_6_000_to_7_200", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_14_400_to_15_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 114033.33333333333, + "resolved_value": 19657.333333333332, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_294fdb23cc02a98334267137" + "resolved_fact_key": "ledger_aggregate_fact_v2_42f1cbfe9fee5eb33f69088d" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_7_200_to_8_400", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_15_600_to_16_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 149043.77777777778, + "resolved_value": 16443.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_5d4a92d292c96a2f440dee5a" + "resolved_fact_key": "ledger_aggregate_fact_v2_aed9bf66bdbc046ee991fcf5" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_8_400_to_9_600", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_16_800_to_18_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 399750.22222222225, + "resolved_value": 13441.111111111111, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad92f85c0ac85ea7bb6e8ca3" + "resolved_fact_key": "ledger_aggregate_fact_v2_7ccb1420b8ca3e26048291b9" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_9_600_to_10_800", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_18_000_to_19_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 386411.6666666667, + "resolved_value": 10728.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e2bbf1fe386cfcd8db712026" + "resolved_fact_key": "ledger_aggregate_fact_v2_a7057ddde3cd2ffaed246687" }, { - "name": "dwp/uc_payment_dist/SINGLE_annual_payment_10_800_to_12_000", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_19_200_to_20_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 104891.11111111111, + "resolved_value": 9653.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_de2719af6e4d5f9ffe65aaee" - } - ] - }, - "dwp.uc.payment_distribution_lone_parent": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_3e228ab480713f15af6e847c" + }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_0_to_1_200", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_20_400_to_21_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 26670.222222222223, + "resolved_value": 6486.888888888889, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7b17c88cf49645b2d3ef44a6" + "resolved_fact_key": "ledger_aggregate_fact_v2_ecfd0dfe25ebc098ade1e902" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_1_200_to_2_400", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_21_600_to_22_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 36208.11111111111, + "resolved_value": 3981.8888888888887, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_765ace417ceafd524ffda4c0" + "resolved_fact_key": "ledger_aggregate_fact_v2_2bbf9ab64d9fde9025452375" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_12_000_to_13_200", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_22_800_to_24_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 125798.44444444444, + "resolved_value": 2761.4444444444443, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_eaddee052a3861f259b93272" + "resolved_fact_key": "ledger_aggregate_fact_v2_f19a927835e2aa12a94f6279" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_13_200_to_14_400", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_2_400_to_3_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 129133.66666666667, + "resolved_value": 12256.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8d66013c8a68e423f507be8" + "resolved_fact_key": "ledger_aggregate_fact_v2_46ba331006269a96f7aee844" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_14_400_to_15_600", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_24_000_to_25_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 115856.66666666667, + "resolved_value": 2131.222222222222, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1bc84efe74c485d143caab7b" + "resolved_fact_key": "ledger_aggregate_fact_v2_dd2ddbef54fc0ec48f61d7b0" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_15_600_to_16_800", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_25_200_to_26_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 125660.22222222222, + "resolved_value": 1475.3333333333333, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e26d2d7e425a94fd9fde3d17" + "resolved_fact_key": "ledger_aggregate_fact_v2_3ea2b4312343be8d41a37265" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_16_800_to_18_000", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_26_400_to_27_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 135836.77777777778, + "resolved_value": 1073.7777777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8fa2e062c33297530d458054" + "resolved_fact_key": "ledger_aggregate_fact_v2_55cf1a8742443b096e81b33e" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_18_000_to_19_200", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_27_600_to_28_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 135444.88888888888, + "resolved_value": 746.3333333333334, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_77cb72042ffb9b2b1af769e3" + "resolved_fact_key": "ledger_aggregate_fact_v2_6cd7a2f97a5e43ba25481719" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_19_200_to_20_400", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_28_800_to_30_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 106341.88888888889, + "resolved_value": 605.7777777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_acb89a96425fd7af119e0c3b" + "resolved_fact_key": "ledger_aggregate_fact_v2_3f50c2d6d58a3a45681f0c5d" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_20_400_to_21_600", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_3_600_to_4_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 85490.44444444444, + "resolved_value": 10945.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3aa5825f5e5e8dbc570c0af1" + "resolved_fact_key": "ledger_aggregate_fact_v2_0ead4e96f4e609a16cf1e53e" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_21_600_to_22_800", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_4_800_to_6_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 80226.88888888889, + "resolved_value": 12492.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c5a0ee450c3ad7f882dfb167" + "resolved_fact_key": "ledger_aggregate_fact_v2_6823b2987ba44d1b85428d2b" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_22_800_to_24_000", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_6_000_to_7_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 71259.55555555556, + "resolved_value": 12979.666666666666, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_13ffca0d11c038fc7d096ec9" + "resolved_fact_key": "ledger_aggregate_fact_v2_3a3fc258bd18da8c60177380" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_2_400_to_3_600", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_7_200_to_8_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 46312.77777777778, + "resolved_value": 16484.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6619e26753d01d76247e1759" + "resolved_fact_key": "ledger_aggregate_fact_v2_b75ef335d484f8dd9ae13a70" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_24_000_to_25_200", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_8_400_to_9_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 51301.666666666664, + "resolved_value": 15272.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_4a935006e5c346bfe0009055" + "resolved_fact_key": "ledger_aggregate_fact_v2_fcd000da1af753b61c9ac5df" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_25_200_to_26_400", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_9_600_to_10_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 43305.22222222222, + "resolved_value": 19142.333333333332, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e64560bd9c14d083cd03c985" + "resolved_fact_key": "ledger_aggregate_fact_v2_3d38fa50aa9bf0e85549ec9a" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_26_400_to_27_600", + "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_10_800_to_12_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 34910.555555555555, + "resolved_value": 13313.333333333334, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8e16d0c97924701eb074c25d" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_6697a9dc6c88a1a0b0472a1e" + } + ] + }, + "dwp.uc.payment_distribution_couple_with_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_27_600_to_28_800", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 28513.0, + "resolved_value": 19073.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf9757018b0d313f20342b59" + "resolved_fact_key": "ledger_aggregate_fact_v2_8c1548028e499fa8399d1246" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_28_800_to_30_000", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 22593.0, + "resolved_value": 22775.777777777777, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6bede883f015e48e86c0a2de" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff2fef9bd96e583203e111d6" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_3_600_to_4_800", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_12_000_to_13_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 60310.11111111111, + "resolved_value": 40009.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b0710535c8b6006db118eb3b" + "resolved_fact_key": "ledger_aggregate_fact_v2_fee1fd2227a87871edfe2bfa" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_4_800_to_6_000", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_13_200_to_14_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 67858.66666666667, + "resolved_value": 39972.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b4008c8b22190b4ee185d4f6" + "resolved_fact_key": "ledger_aggregate_fact_v2_3b0427c86dc3df13761ab5b0" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_6_000_to_7_200", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_14_400_to_15_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 89577.44444444444, + "resolved_value": 40518.77777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d1fadffae053bf60d7fcd7e" + "resolved_fact_key": "ledger_aggregate_fact_v2_bfd9a57597b46f356ef9cfc9" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_7_200_to_8_400", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_15_600_to_16_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 116076.0, + "resolved_value": 37118.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fae65610a14d6c22f475d757" + "resolved_fact_key": "ledger_aggregate_fact_v2_328ed88b561971d4ee47d852" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_8_400_to_9_600", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_16_800_to_18_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 97511.0, + "resolved_value": 37177.77777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_540c0869e23edc4a402166bf" + "resolved_fact_key": "ledger_aggregate_fact_v2_c50c761ddfaab3cbfba62bfd" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_9_600_to_10_800", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_18_000_to_19_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 102343.0, + "resolved_value": 37164.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a170bf444a17ae88a80766b0" + "resolved_fact_key": "ledger_aggregate_fact_v2_74d32efc9f1984f60cbd9397" }, { - "name": "dwp/uc_payment_dist/LONE_PARENT_annual_payment_10_800_to_12_000", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_19_200_to_20_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 123718.11111111111, + "resolved_value": 33309.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b7d0d6add859217e797a66ea" - } - ] - }, - "dwp.uc.payment_distribution_couple_no_children": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_90b7e15c6554b1c74e7055f3" + }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_0_to_1_200", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_20_400_to_21_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 7506.333333333333, + "resolved_value": 29102.555555555555, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8af6f4ef9d70ded4a4bf6b5" + "resolved_fact_key": "ledger_aggregate_fact_v2_96f9b06f2d2afb65af9a224a" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_1_200_to_2_400", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_21_600_to_22_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 8797.0, + "resolved_value": 27534.666666666668, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_28514ff922f7b00a4706e74b" + "resolved_fact_key": "ledger_aggregate_fact_v2_e65a50de282324e8c188863a" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_12_000_to_13_200", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_22_800_to_24_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 16121.444444444445, + "resolved_value": 25584.777777777777, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8b8e20276b7af9f670009f64" + "resolved_fact_key": "ledger_aggregate_fact_v2_16f48d435925ffa44f4d6871" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_13_200_to_14_400", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 13317.333333333334, + "resolved_value": 26502.666666666668, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_22e83b92481a8b2267a15309" + "resolved_fact_key": "ledger_aggregate_fact_v2_93fd0534df01d1dade53397e" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_14_400_to_15_600", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_24_000_to_25_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 19657.333333333332, + "resolved_value": 22927.777777777777, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_42f1cbfe9fee5eb33f69088d" + "resolved_fact_key": "ledger_aggregate_fact_v2_ffb787487a36c86f94d25a25" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_15_600_to_16_800", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_25_200_to_26_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 16443.222222222223, + "resolved_value": 20334.666666666668, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_aed9bf66bdbc046ee991fcf5" + "resolved_fact_key": "ledger_aggregate_fact_v2_2f4d504be6f184b7834f2687" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_16_800_to_18_000", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_26_400_to_27_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 13441.111111111111, + "resolved_value": 17535.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7ccb1420b8ca3e26048291b9" + "resolved_fact_key": "ledger_aggregate_fact_v2_719022eef2836c069c4b02d0" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_18_000_to_19_200", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_27_600_to_28_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 10728.555555555555, + "resolved_value": 15399.888888888889, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_a7057ddde3cd2ffaed246687" + "resolved_fact_key": "ledger_aggregate_fact_v2_3b1d8f6516b32e39ecad3873" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_19_200_to_20_400", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_28_800_to_30_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 9653.222222222223, + "resolved_value": 12836.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3e228ab480713f15af6e847c" + "resolved_fact_key": "ledger_aggregate_fact_v2_115a9ea1e35d76db13756149" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_20_400_to_21_600", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_3_600_to_4_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 6486.888888888889, + "resolved_value": 29027.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ecfd0dfe25ebc098ade1e902" + "resolved_fact_key": "ledger_aggregate_fact_v2_255e8c862df5351282c29809" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_21_600_to_22_800", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_4_800_to_6_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 3981.8888888888887, + "resolved_value": 32427.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2bbf9ab64d9fde9025452375" + "resolved_fact_key": "ledger_aggregate_fact_v2_32261034f242507c0a7337b3" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_22_800_to_24_000", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_6_000_to_7_200", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2761.4444444444443, + "resolved_value": 34956.88888888889, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f19a927835e2aa12a94f6279" + "resolved_fact_key": "ledger_aggregate_fact_v2_6f40664df124c4dca50524b8" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_2_400_to_3_600", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_7_200_to_8_400", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 12256.0, + "resolved_value": 37410.77777777778, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_46ba331006269a96f7aee844" + "resolved_fact_key": "ledger_aggregate_fact_v2_27b091b1a00bc33ab68139f8" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_24_000_to_25_200", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_8_400_to_9_600", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 2131.222222222222, + "resolved_value": 39910.333333333336, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd2ddbef54fc0ec48f61d7b0" + "resolved_fact_key": "ledger_aggregate_fact_v2_22b16b470c0b51499fb2f042" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_25_200_to_26_400", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_9_600_to_10_800", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1475.3333333333333, + "resolved_value": 39368.0, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3ea2b4312343be8d41a37265" + "resolved_fact_key": "ledger_aggregate_fact_v2_7dbca9e2f8508f1066399b73" }, { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_26_400_to_27_600", + "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_10_800_to_12_000", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 1073.7777777777778, + "resolved_value": 40805.444444444445, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_55cf1a8742443b096e81b33e" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_23cf62e7e58211e783c52d2e" + } + ] + }, + "dwp.uc.scotland_households_child_under_1": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_27_600_to_28_800", + "name": "dwp.uc.scotland_households_child_under_1", "status": "active", "matched_fact_count_overall": 9, "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 746.3333333333334, + "resolved_value": 14333.222222222223, "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6cd7a2f97a5e43ba25481719" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_e88b27e010e08ac8d36d0d30" + } + ] + }, + "dwp.uc.two_child_limit.households_affected": { + "status": "active", + "candidates": [ + { + "name": "dwp.uc.two_child_limit.households_affected", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 469780.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_860a48172c62298ceb00c20b" + } + ] + }, + "dwp.uc.two_child_limit.children_affected": { + "status": "active", + "candidates": [ + { + "name": "dwp.uc.two_child_limit.children_affected", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 597920.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_4378e45ac129e036b4a6ca03" + } + ] + }, + "dwp.uc.two_child_limit.children_in_affected_households": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_28_800_to_30_000", + "name": "dwp.uc.two_child_limit.children_in_affected_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 605.7777777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3f50c2d6d58a3a45681f0c5d" - }, + "resolved_value": 1665540.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_05774e34488c474df7f84742" + } + ] + }, + "dwp.uc.two_child_limit.households_3_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_3_600_to_4_800", + "name": "dwp.uc.two_child_limit.households_3_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 10945.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0ead4e96f4e609a16cf1e53e" - }, + "resolved_value": 297310.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_dca7734c17910c213e397741" + } + ] + }, + "dwp.uc.two_child_limit.children_in_3_children_households": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_4_800_to_6_000", + "name": "dwp.uc.two_child_limit.children_in_3_children_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12492.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6823b2987ba44d1b85428d2b" - }, + "resolved_value": 891930.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_515b2aeb394a9a9a1fd2d195" + } + ] + }, + "dwp.uc.two_child_limit.households_4_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_6_000_to_7_200", + "name": "dwp.uc.two_child_limit.households_4_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 12979.666666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3a3fc258bd18da8c60177380" - }, + "resolved_value": 117190.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_a78a141d4018bdd92678b497" + } + ] + }, + "dwp.uc.two_child_limit.children_in_4_children_households": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_7_200_to_8_400", + "name": "dwp.uc.two_child_limit.children_in_4_children_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16484.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_b75ef335d484f8dd9ae13a70" - }, + "resolved_value": 468760.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_adef094060710c5b354e7ac4" + } + ] + }, + "dwp.uc.two_child_limit.households_5_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_8_400_to_9_600", + "name": "dwp.uc.two_child_limit.households_5_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 15272.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcd000da1af753b61c9ac5df" - }, + "resolved_value": 37020.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_2c9cfcd7cc862c9c1dd57e4d" + } + ] + }, + "dwp.uc.two_child_limit.children_in_5_children_households": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_9_600_to_10_800", + "name": "dwp.uc.two_child_limit.children_in_5_children_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 19142.333333333332, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d38fa50aa9bf0e85549ec9a" - }, + "resolved_value": 185120.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_2134e60314c98faf54df2498" + } + ] + }, + "dwp.uc.two_child_limit.households_6_plus_children": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_NO_CHILDREN_annual_payment_10_800_to_12_000", + "name": "dwp.uc.two_child_limit.households_6_plus_children", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13313.333333333334, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6697a9dc6c88a1a0b0472a1e" + "resolved_value": 18260.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_e6302f9f933c14e97fc2fcae" } ] }, - "dwp.uc.payment_distribution_couple_with_children": { + "dwp.uc.two_child_limit.children_in_6_plus_children_households": { "status": "active", "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_0_to_1_200", + "name": "dwp.uc.two_child_limit.children_in_6_plus_children_households", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 19073.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_8c1548028e499fa8399d1246" - }, + "resolved_value": 119720.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_235cb4e779dd669dad2cd421" + } + ] + }, + "dwp.uc.two_child_limit.households_claimant_pip": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_1_200_to_2_400", + "name": "dwp.uc.two_child_limit.households_claimant_pip", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 22775.777777777777, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff2fef9bd96e583203e111d6" - }, + "resolved_value": 65280.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_55dd86462d71be247206b5a2" + } + ] + }, + "dwp.uc.two_child_limit.children_claimant_pip": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_12_000_to_13_200", + "name": "dwp.uc.two_child_limit.children_claimant_pip", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 40009.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_fee1fd2227a87871edfe2bfa" - }, + "resolved_value": 235270.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe554fcdcb22a77d71c01537" + } + ] + }, + "dwp.uc.two_child_limit.households_disabled_child_element": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_13_200_to_14_400", + "name": "dwp.uc.two_child_limit.households_disabled_child_element", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 39972.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b0427c86dc3df13761ab5b0" - }, + "resolved_value": 129630.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_535ef3b4afd474ea14d16d27" + } + ] + }, + "dwp.uc.two_child_limit.children_disabled_child_element": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_14_400_to_15_600", + "name": "dwp.uc.two_child_limit.children_disabled_child_element", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 40518.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_bfd9a57597b46f356ef9cfc9" - }, + "resolved_value": 479460.0, + "resolved_fact_period": "2025-04", + "resolved_fact_key": "ledger_aggregate_fact_v2_ac642b7002518167b56e1537" + } + ] + }, + "ons.population.uk_total": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_15_600_to_16_800", + "name": "ons.population.uk_total", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 37118.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_328ed88b561971d4ee47d852" - }, + "resolved_value": 69281437.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_6c212695ea75be0d2a635e9b" + } + ] + }, + "ons.population.age_0_9_by_region": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_16_800_to_18_000", + "name": "ons.population.age_0_9_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 37177.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_c50c761ddfaab3cbfba62bfd" + "resolved_value": 285165.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c796672d4d88aa11ab15a31a" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_18_000_to_19_200", + "name": "ons.population.age_0_9_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 37164.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_74d32efc9f1984f60cbd9397" + "resolved_value": 865892.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_de0fc360f660f7a387628062" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_19_200_to_20_400", + "name": "ons.population.age_0_9_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 33309.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_90b7e15c6554b1c74e7055f3" + "resolved_value": 626938.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_cbc8ee6d7552af4ba61edcb1" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_20_400_to_21_600", + "name": "ons.population.age_0_9_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 29102.555555555555, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f9b06f2d2afb65af9a224a" + "resolved_value": 543004.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f858f629484e7989a9dc1f0b" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_21_600_to_22_800", + "name": "ons.population.age_0_9_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 27534.666666666668, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e65a50de282324e8c188863a" + "resolved_value": 718837.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_de2d9b45547f640fbc7ebb5a" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_22_800_to_24_000", + "name": "ons.population.age_0_9_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 25584.777777777777, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_16f48d435925ffa44f4d6871" + "resolved_value": 744698.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fec32a4b3417958969f5f2d9" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_2_400_to_3_600", + "name": "ons.population.age_0_9_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 26502.666666666668, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_93fd0534df01d1dade53397e" + "resolved_value": 1054493.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_cdd134faa924b905bd8a36ad" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_24_000_to_25_200", + "name": "ons.population.age_0_9_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 22927.777777777777, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffb787487a36c86f94d25a25" + "resolved_value": 1059434.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f0ef951a6bad79d44726fe11" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_25_200_to_26_400", + "name": "ons.population.age_0_9_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 20334.666666666668, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_2f4d504be6f184b7834f2687" + "resolved_value": 575506.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d6a250010241c987a217b54f" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_26_400_to_27_600", + "name": "ons.population.age_0_9_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 17535.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_719022eef2836c069c4b02d0" + "resolved_value": 321552.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_eef268031d128fde4eec5d91" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_27_600_to_28_800", + "name": "ons.population.age_0_9_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 15399.888888888889, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_3b1d8f6516b32e39ecad3873" + "resolved_value": 527989.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_28_800_to_30_000", + "name": "ons.population.age_0_9_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 12836.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_115a9ea1e35d76db13756149" - }, + "resolved_value": 229505.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_eb8519582dac5a21a72f8360" + } + ] + }, + "ons.population.age_10_19_by_region": { + "status": "active", + "candidates": [ { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_3_600_to_4_800", + "name": "ons.population.age_10_19_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 29027.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_255e8c862df5351282c29809" + "resolved_value": 326306.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ce36092d33f50f712f620485" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_4_800_to_6_000", + "name": "ons.population.age_10_19_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 32427.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_32261034f242507c0a7337b3" + "resolved_value": 952864.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f6fc45432de26717dc50151d" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_6_000_to_7_200", + "name": "ons.population.age_10_19_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 34956.88888888889, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_6f40664df124c4dca50524b8" + "resolved_value": 696780.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f1942c03893e2aeccb514e34" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_7_200_to_8_400", + "name": "ons.population.age_10_19_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 37410.77777777778, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_27b091b1a00bc33ab68139f8" + "resolved_value": 615630.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d96b0e1445c879a8267ef553" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_8_400_to_9_600", + "name": "ons.population.age_10_19_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 39910.333333333336, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_22b16b470c0b51499fb2f042" + "resolved_value": 785062.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff921d8727a6c1ea11548896" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_9_600_to_10_800", + "name": "ons.population.age_10_19_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 39368.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7dbca9e2f8508f1066399b73" + "resolved_value": 785091.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d66fd1b48bc1e9ae4d38f778" }, { - "name": "dwp/uc_payment_dist/COUPLE_WITH_CHILDREN_annual_payment_10_800_to_12_000", + "name": "ons.population.age_10_19_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 40805.444444444445, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_23cf62e7e58211e783c52d2e" - } - ] - }, - "dwp.uc.scotland_households_child_under_1": { - "status": "active", - "candidates": [ + "resolved_value": 1068691.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8b79fef8b80acc1deb297b7" + }, { - "name": "dwp.uc.scotland_households_child_under_1", + "name": "ons.population.age_10_19_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 14333.222222222223, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_e88b27e010e08ac8d36d0d30" - } - ] - }, - "dwp.uc.two_child_limit.households_affected": { - "status": "active", - "candidates": [ + "resolved_value": 1183235.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ba4c8f8e6cb789626f191523" + }, { - "name": "dwp.uc.two_child_limit.households_affected", + "name": "ons.population.age_10_19_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 469780.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_860a48172c62298ceb00c20b" - } - ] - }, - "dwp.uc.two_child_limit.children_affected": { - "status": "active", - "candidates": [ + "resolved_value": 677228.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8ea04bba18d65ed2ac0dd74" + }, { - "name": "dwp.uc.two_child_limit.children_affected", + "name": "ons.population.age_10_19_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 597920.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_4378e45ac129e036b4a6ca03" - } - ] - }, - "dwp.uc.two_child_limit.children_in_affected_households": { - "status": "active", - "candidates": [ + "resolved_value": 374851.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f040814c3de37f315671a60d" + }, { - "name": "dwp.uc.two_child_limit.children_in_affected_households", + "name": "ons.population.age_10_19_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 1665540.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_05774e34488c474df7f84742" - } - ] - }, - "dwp.uc.two_child_limit.households_3_children": { - "status": "active", - "candidates": [ + "resolved_value": 612935.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d8cb95f3b8a4eb5725ec1e0d" + }, { - "name": "dwp.uc.two_child_limit.households_3_children", + "name": "ons.population.age_10_19_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 297310.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_dca7734c17910c213e397741" + "resolved_value": 252764.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef301c6ab42b35eb692e20b0" } ] }, - "dwp.uc.two_child_limit.children_in_3_children_households": { + "ons.population.age_20_29_by_region": { "status": "active", "candidates": [ { - "name": "dwp.uc.two_child_limit.children_in_3_children_households", + "name": "ons.population.age_20_29_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 891930.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_515b2aeb394a9a9a1fd2d195" - } - ] - }, - "dwp.uc.two_child_limit.households_4_children": { - "status": "active", - "candidates": [ + "resolved_value": 343015.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ebe0b2ced4987cd701db581a" + }, { - "name": "dwp.uc.two_child_limit.households_4_children", + "name": "ons.population.age_20_29_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 117190.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_a78a141d4018bdd92678b497" - } - ] - }, - "dwp.uc.two_child_limit.children_in_4_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 986590.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe94b1572d6db93b57407bcd" + }, { - "name": "dwp.uc.two_child_limit.children_in_4_children_households", + "name": "ons.population.age_20_29_by_region@E12000003", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 468760.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_adef094060710c5b354e7ac4" - } - ] - }, - "dwp.uc.two_child_limit.households_5_children": { - "status": "active", - "candidates": [ + "resolved_value": 717479.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_cb721748c503839a9229a404" + }, { - "name": "dwp.uc.two_child_limit.households_5_children", + "name": "ons.population.age_20_29_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 37020.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_2c9cfcd7cc862c9c1dd57e4d" - } - ] - }, - "dwp.uc.two_child_limit.children_in_5_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 612108.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7be7895d4f680a502caeb4b" + }, { - "name": "dwp.uc.two_child_limit.children_in_5_children_households", + "name": "ons.population.age_20_29_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 185120.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_2134e60314c98faf54df2498" - } - ] - }, - "dwp.uc.two_child_limit.households_6_plus_children": { - "status": "active", - "candidates": [ + "resolved_value": 766058.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f539e665a5478f92346bb4d4" + }, { - "name": "dwp.uc.two_child_limit.households_6_plus_children", + "name": "ons.population.age_20_29_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 18260.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_e6302f9f933c14e97fc2fcae" - } - ] - }, - "dwp.uc.two_child_limit.children_in_6_plus_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 727218.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff31c89cfa957bdd279c9947" + }, { - "name": "dwp.uc.two_child_limit.children_in_6_plus_children_households", + "name": "ons.population.age_20_29_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 119720.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_235cb4e779dd669dad2cd421" - } - ] - }, - "dwp.uc.two_child_limit.households_claimant_pip": { - "status": "active", - "candidates": [ + "resolved_value": 1508607.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f0ffc4e5795625b9238d6dde" + }, { - "name": "dwp.uc.two_child_limit.households_claimant_pip", + "name": "ons.population.age_20_29_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 65280.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_55dd86462d71be247206b5a2" - } - ] - }, - "dwp.uc.two_child_limit.children_claimant_pip": { - "status": "active", - "candidates": [ + "resolved_value": 1066121.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f3a720e9d1d4664e83307a9a" + }, { - "name": "dwp.uc.two_child_limit.children_claimant_pip", + "name": "ons.population.age_20_29_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 235270.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe554fcdcb22a77d71c01537" - } - ] - }, - "dwp.uc.two_child_limit.households_disabled_child_element": { - "status": "active", - "candidates": [ + "resolved_value": 684393.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe520978b4f4105aa292a3f5" + }, { - "name": "dwp.uc.two_child_limit.households_disabled_child_element", + "name": "ons.population.age_20_29_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 129630.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_535ef3b4afd474ea14d16d27" - } - ] - }, - "dwp.uc.two_child_limit.children_disabled_child_element": { - "status": "active", - "candidates": [ + "resolved_value": 380557.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe44434fdb2e33179826ee35" + }, { - "name": "dwp.uc.two_child_limit.children_disabled_child_element", + "name": "ons.population.age_20_29_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 1, - "matched_fact_count_at_or_before_period": 1, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 479460.0, - "resolved_fact_period": "2025-04", - "resolved_fact_key": "ledger_aggregate_fact_v2_ac642b7002518167b56e1537" - } - ] - }, - "ons.population.uk_total": { - "status": "active", - "candidates": [ + "resolved_value": 703554.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_dadba40aea2eb5dcdb2e5d6e" + }, { - "name": "ons.population.uk_total", + "name": "ons.population.age_20_29_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 20, + "matched_fact_count_at_or_before_period": 20, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 69281437.0, + "resolved_value": 219525.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_6c212695ea75be0d2a635e9b" + "resolved_fact_key": "ledger_aggregate_fact_v2_afe826389a344a01c4be2862" } ] }, - "ons.population.age_0_9_by_region": { + "ons.population.age_30_39_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_0_9_by_region@E12000001", + "name": "ons.population.age_30_39_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 285165.0, + "resolved_value": 363357.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c796672d4d88aa11ab15a31a" + "resolved_fact_key": "ledger_aggregate_fact_v2_ceb94ab430de1f0bc8c19ce4" }, { - "name": "ons.population.age_0_9_by_region@E12000002", + "name": "ons.population.age_30_39_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 865892.0, + "resolved_value": 1064968.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de0fc360f660f7a387628062" + "resolved_fact_key": "ledger_aggregate_fact_v2_eeb6e6194f0405a4b7010913" }, { - "name": "ons.population.age_0_9_by_region@E12000003", + "name": "ons.population.age_30_39_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 626938.0, + "resolved_value": 770809.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cbc8ee6d7552af4ba61edcb1" + "resolved_fact_key": "ledger_aggregate_fact_v2_ebc2a149da9287a3a2b28d45" }, { - "name": "ons.population.age_0_9_by_region@E12000004", + "name": "ons.population.age_30_39_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 543004.0, + "resolved_value": 676709.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f858f629484e7989a9dc1f0b" + "resolved_fact_key": "ledger_aggregate_fact_v2_fefffb16e9e1a25fd0da3435" }, { - "name": "ons.population.age_0_9_by_region@E12000005", + "name": "ons.population.age_30_39_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 718837.0, + "resolved_value": 839114.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de2d9b45547f640fbc7ebb5a" + "resolved_fact_key": "ledger_aggregate_fact_v2_eaee3d4e99154692dbad24b9" }, { - "name": "ons.population.age_0_9_by_region@E12000006", + "name": "ons.population.age_30_39_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 744698.0, + "resolved_value": 895639.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fec32a4b3417958969f5f2d9" + "resolved_fact_key": "ledger_aggregate_fact_v2_fbb89267af1b9a1a349f3274" }, { - "name": "ons.population.age_0_9_by_region@E12000007", + "name": "ons.population.age_30_39_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1054493.0, + "resolved_value": 1537372.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cdd134faa924b905bd8a36ad" + "resolved_fact_key": "ledger_aggregate_fact_v2_c7d5874566b099143ddbac28" }, { - "name": "ons.population.age_0_9_by_region@E12000008", + "name": "ons.population.age_30_39_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1059434.0, + "resolved_value": 1284552.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0ef951a6bad79d44726fe11" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4aa5baed49b53887253b70" }, { - "name": "ons.population.age_0_9_by_region@E12000009", + "name": "ons.population.age_30_39_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 575506.0, + "resolved_value": 742082.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d6a250010241c987a217b54f" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8c6ce01a5aa83ce392ccf3a" }, { - "name": "ons.population.age_0_9_by_region@W92000004", + "name": "ons.population.age_30_39_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 321552.0, + "resolved_value": 410248.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eef268031d128fde4eec5d91" + "resolved_fact_key": "ledger_aggregate_fact_v2_fa74c4da871af17e8af431d6" }, { - "name": "ons.population.age_0_9_by_region@S92000003", + "name": "ons.population.age_30_39_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 527989.0, + "resolved_value": 733480.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" + "resolved_fact_key": "ledger_aggregate_fact_v2_f045b554aebb8f1b21df5a5c" }, { - "name": "ons.population.age_0_9_by_region@N92000002", + "name": "ons.population.age_30_39_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 229505.0, + "resolved_value": 254067.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb8519582dac5a21a72f8360" + "resolved_fact_key": "ledger_aggregate_fact_v2_eb383d007487ef1df14f4946" } ] }, - "ons.population.age_10_19_by_region": { + "ons.population.age_40_49_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_10_19_by_region@E12000001", + "name": "ons.population.age_40_49_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 326306.0, + "resolved_value": 320860.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ce36092d33f50f712f620485" + "resolved_fact_key": "ledger_aggregate_fact_v2_f081bcb6c2e794e8ec3b0161" }, { - "name": "ons.population.age_10_19_by_region@E12000002", + "name": "ons.population.age_40_49_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 952864.0, + "resolved_value": 930967.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6fc45432de26717dc50151d" + "resolved_fact_key": "ledger_aggregate_fact_v2_f7744877e123c00b96511818" }, { - "name": "ons.population.age_10_19_by_region@E12000003", + "name": "ons.population.age_40_49_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 696780.0, + "resolved_value": 674349.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1942c03893e2aeccb514e34" + "resolved_fact_key": "ledger_aggregate_fact_v2_d6e708c298712163b552e6c7" }, { - "name": "ons.population.age_10_19_by_region@E12000004", + "name": "ons.population.age_40_49_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 615630.0, + "resolved_value": 610611.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d96b0e1445c879a8267ef553" + "resolved_fact_key": "ledger_aggregate_fact_v2_e861cd162b6b06a1107ca177" }, { - "name": "ons.population.age_10_19_by_region@E12000005", + "name": "ons.population.age_40_49_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 785062.0, + "resolved_value": 746341.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff921d8727a6c1ea11548896" + "resolved_fact_key": "ledger_aggregate_fact_v2_fa28a64a0b8ec87502b44a9f" }, { - "name": "ons.population.age_10_19_by_region@E12000006", + "name": "ons.population.age_40_49_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 785091.0, + "resolved_value": 838578.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d66fd1b48bc1e9ae4d38f778" + "resolved_fact_key": "ledger_aggregate_fact_v2_f94400c214a5c3c3847cc562" }, { - "name": "ons.population.age_10_19_by_region@E12000007", + "name": "ons.population.age_40_49_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1068691.0, + "resolved_value": 1268973.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8b79fef8b80acc1deb297b7" + "resolved_fact_key": "ledger_aggregate_fact_v2_fb8228a78efb8cdb3dd46764" }, { - "name": "ons.population.age_10_19_by_region@E12000008", + "name": "ons.population.age_40_49_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1183235.0, + "resolved_value": 1255951.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba4c8f8e6cb789626f191523" + "resolved_fact_key": "ledger_aggregate_fact_v2_edac715ea904f29dbd3332f9" }, { - "name": "ons.population.age_10_19_by_region@E12000009", + "name": "ons.population.age_40_49_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 677228.0, + "resolved_value": 688417.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8ea04bba18d65ed2ac0dd74" + "resolved_fact_key": "ledger_aggregate_fact_v2_f6ecf5ebd09a5d638cf6dd15" }, { - "name": "ons.population.age_10_19_by_region@W92000004", + "name": "ons.population.age_40_49_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 374851.0, + "resolved_value": 365951.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f040814c3de37f315671a60d" + "resolved_fact_key": "ledger_aggregate_fact_v2_f6496b4ebd88792d288206a1" }, { - "name": "ons.population.age_10_19_by_region@S92000003", + "name": "ons.population.age_40_49_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 612935.0, + "resolved_value": 675368.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d8cb95f3b8a4eb5725ec1e0d" + "resolved_fact_key": "ledger_aggregate_fact_v2_e159eb5144ceae58dccb4dc0" }, { - "name": "ons.population.age_10_19_by_region@N92000002", + "name": "ons.population.age_40_49_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 252764.0, + "resolved_value": 246140.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef301c6ab42b35eb692e20b0" + "resolved_fact_key": "ledger_aggregate_fact_v2_b71979cb27997e512ea68888" } ] }, - "ons.population.age_20_29_by_region": { + "ons.population.age_50_59_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_20_29_by_region@E12000001", + "name": "ons.population.age_50_59_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 343015.0, + "resolved_value": 360074.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ebe0b2ced4987cd701db581a" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8febade5d1aa4eff5515f79" }, { - "name": "ons.population.age_20_29_by_region@E12000002", + "name": "ons.population.age_50_59_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 986590.0, + "resolved_value": 995810.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe94b1572d6db93b57407bcd" + "resolved_fact_key": "ledger_aggregate_fact_v2_ce316c567d2d3919bad74247" }, { - "name": "ons.population.age_20_29_by_region@E12000003", + "name": "ons.population.age_50_59_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 717479.0, + "resolved_value": 736903.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cb721748c503839a9229a404" + "resolved_fact_key": "ledger_aggregate_fact_v2_f07e470e70895701083be7b4" }, { - "name": "ons.population.age_20_29_by_region@E12000004", + "name": "ons.population.age_50_59_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 612108.0, + "resolved_value": 676307.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7be7895d4f680a502caeb4b" + "resolved_fact_key": "ledger_aggregate_fact_v2_fc3b848c0d546908542f7522" }, { - "name": "ons.population.age_20_29_by_region@E12000005", + "name": "ons.population.age_50_59_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 766058.0, + "resolved_value": 794143.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f539e665a5478f92346bb4d4" + "resolved_fact_key": "ledger_aggregate_fact_v2_eced9fed4ca113ee655134b7" }, { - "name": "ons.population.age_20_29_by_region@E12000006", + "name": "ons.population.age_50_59_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 727218.0, + "resolved_value": 866946.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff31c89cfa957bdd279c9947" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8011436193a375ac63a33af" }, { - "name": "ons.population.age_20_29_by_region@E12000007", + "name": "ons.population.age_50_59_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1508607.0, + "resolved_value": 1087518.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0ffc4e5795625b9238d6dde" + "resolved_fact_key": "ledger_aggregate_fact_v2_c0999183e74a6f6978377427" }, { - "name": "ons.population.age_20_29_by_region@E12000008", + "name": "ons.population.age_50_59_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1066121.0, + "resolved_value": 1287719.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f3a720e9d1d4664e83307a9a" + "resolved_fact_key": "ledger_aggregate_fact_v2_f5b6740db34f7f702bb230fb" }, { - "name": "ons.population.age_20_29_by_region@E12000009", + "name": "ons.population.age_50_59_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 684393.0, + "resolved_value": 784718.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe520978b4f4105aa292a3f5" + "resolved_fact_key": "ledger_aggregate_fact_v2_cf32f90895454cdb82d3a611" }, { - "name": "ons.population.age_20_29_by_region@W92000004", + "name": "ons.population.age_50_59_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 380557.0, + "resolved_value": 424694.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe44434fdb2e33179826ee35" + "resolved_fact_key": "ledger_aggregate_fact_v2_ed905faab304a40013587ffd" }, { - "name": "ons.population.age_20_29_by_region@S92000003", + "name": "ons.population.age_50_59_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 703554.0, + "resolved_value": 766715.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dadba40aea2eb5dcdb2e5d6e" + "resolved_fact_key": "ledger_aggregate_fact_v2_f332e28940d1c94b1e2dec31" }, { - "name": "ons.population.age_20_29_by_region@N92000002", + "name": "ons.population.age_50_59_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 219525.0, + "resolved_value": 255269.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_afe826389a344a01c4be2862" + "resolved_fact_key": "ledger_aggregate_fact_v2_f786aada1891e9f309902c1c" } ] }, - "ons.population.age_30_39_by_region": { + "ons.population.age_60_69_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_30_39_by_region@E12000001", + "name": "ons.population.age_60_69_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 363357.0, + "resolved_value": 349719.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ceb94ab430de1f0bc8c19ce4" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4466f1cb6fb29ce9b132b0" }, { - "name": "ons.population.age_30_39_by_region@E12000002", + "name": "ons.population.age_60_69_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 1064968.0, + "resolved_value": 884043.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eeb6e6194f0405a4b7010913" + "resolved_fact_key": "ledger_aggregate_fact_v2_f861d328dbb8a01929eb1e91" }, { - "name": "ons.population.age_30_39_by_region@E12000003", + "name": "ons.population.age_60_69_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 770809.0, + "resolved_value": 652931.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ebc2a149da9287a3a2b28d45" + "resolved_fact_key": "ledger_aggregate_fact_v2_f9ab6846d67db88fda81fa30" }, { - "name": "ons.population.age_30_39_by_region@E12000004", + "name": "ons.population.age_60_69_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 676709.0, + "resolved_value": 591429.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fefffb16e9e1a25fd0da3435" + "resolved_fact_key": "ledger_aggregate_fact_v2_e884ef403c95938c7ebf961b" }, { - "name": "ons.population.age_30_39_by_region@E12000005", + "name": "ons.population.age_60_69_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 839114.0, + "resolved_value": 677922.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eaee3d4e99154692dbad24b9" + "resolved_fact_key": "ledger_aggregate_fact_v2_fd4d62d07376896553d9fb66" }, { - "name": "ons.population.age_30_39_by_region@E12000006", + "name": "ons.population.age_60_69_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 895639.0, + "resolved_value": 744651.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbb89267af1b9a1a349f3274" + "resolved_fact_key": "ledger_aggregate_fact_v2_f77f96051d8340645148d138" }, { - "name": "ons.population.age_30_39_by_region@E12000007", + "name": "ons.population.age_60_69_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1537372.0, + "resolved_value": 787666.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c7d5874566b099143ddbac28" + "resolved_fact_key": "ledger_aggregate_fact_v2_e9f63f0939b77a41ec815de0" }, { - "name": "ons.population.age_30_39_by_region@E12000008", + "name": "ons.population.age_60_69_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1284552.0, + "resolved_value": 1089421.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4aa5baed49b53887253b70" + "resolved_fact_key": "ledger_aggregate_fact_v2_f8667b0358441f18c2f8e548" }, { - "name": "ons.population.age_30_39_by_region@E12000009", + "name": "ons.population.age_60_69_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 742082.0, + "resolved_value": 736639.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8c6ce01a5aa83ce392ccf3a" + "resolved_fact_key": "ledger_aggregate_fact_v2_f923cb193de625676c40b5c4" }, { - "name": "ons.population.age_30_39_by_region@W92000004", + "name": "ons.population.age_60_69_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 410248.0, + "resolved_value": 401775.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa74c4da871af17e8af431d6" + "resolved_fact_key": "ledger_aggregate_fact_v2_f518ad65099be8a424a62142" }, { - "name": "ons.population.age_30_39_by_region@S92000003", + "name": "ons.population.age_60_69_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 733480.0, + "resolved_value": 721727.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f045b554aebb8f1b21df5a5c" + "resolved_fact_key": "ledger_aggregate_fact_v2_e893656e104d3c1c375fa5e7" }, { - "name": "ons.population.age_30_39_by_region@N92000002", + "name": "ons.population.age_60_69_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 254067.0, + "resolved_value": 223111.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb383d007487ef1df14f4946" + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f6e8f32b460fefc304aeee" } ] }, - "ons.population.age_40_49_by_region": { + "ons.population.age_70_79_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_40_49_by_region@E12000001", + "name": "ons.population.age_70_79_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 320860.0, + "resolved_value": 265573.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f081bcb6c2e794e8ec3b0161" + "resolved_fact_key": "ledger_aggregate_fact_v2_f135bc83bf0e2495ccab922b" }, { - "name": "ons.population.age_40_49_by_region@E12000002", + "name": "ons.population.age_70_79_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 930967.0, + "resolved_value": 669277.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7744877e123c00b96511818" + "resolved_fact_key": "ledger_aggregate_fact_v2_f18853f5a9046c59334188d3" }, { - "name": "ons.population.age_40_49_by_region@E12000003", + "name": "ons.population.age_70_79_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 674349.0, + "resolved_value": 504131.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d6e708c298712163b552e6c7" + "resolved_fact_key": "ledger_aggregate_fact_v2_f71c0090e322cc6b02a80193" }, { - "name": "ons.population.age_40_49_by_region@E12000004", + "name": "ons.population.age_70_79_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 610611.0, + "resolved_value": 466530.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e861cd162b6b06a1107ca177" + "resolved_fact_key": "ledger_aggregate_fact_v2_f1eaa2a27d34d75f4fcaf147" }, { - "name": "ons.population.age_40_49_by_region@E12000005", + "name": "ons.population.age_70_79_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 746341.0, + "resolved_value": 528207.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa28a64a0b8ec87502b44a9f" + "resolved_fact_key": "ledger_aggregate_fact_v2_f6ed607ecc20a6bd1c0c8bef" }, { - "name": "ons.population.age_40_49_by_region@E12000006", + "name": "ons.population.age_70_79_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 838578.0, + "resolved_value": 599882.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f94400c214a5c3c3847cc562" + "resolved_fact_key": "ledger_aggregate_fact_v2_ef2c110c9bb5462379338b17" }, { - "name": "ons.population.age_40_49_by_region@E12000007", + "name": "ons.population.age_70_79_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1268973.0, + "resolved_value": 485057.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb8228a78efb8cdb3dd46764" + "resolved_fact_key": "ledger_aggregate_fact_v2_d9b7f415855dd808a1aee77c" }, { - "name": "ons.population.age_40_49_by_region@E12000008", + "name": "ons.population.age_70_79_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1255951.0, + "resolved_value": 865392.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edac715ea904f29dbd3332f9" + "resolved_fact_key": "ledger_aggregate_fact_v2_dea0c6655095781f862cf7ac" }, { - "name": "ons.population.age_40_49_by_region@E12000009", + "name": "ons.population.age_70_79_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 688417.0, + "resolved_value": 618254.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6ecf5ebd09a5d638cf6dd15" + "resolved_fact_key": "ledger_aggregate_fact_v2_e8898137aad748593321b2fb" }, { - "name": "ons.population.age_40_49_by_region@W92000004", + "name": "ons.population.age_70_79_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 365951.0, + "resolved_value": 321668.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6496b4ebd88792d288206a1" + "resolved_fact_key": "ledger_aggregate_fact_v2_f1de159eac6f90c69f7aef22" }, { - "name": "ons.population.age_40_49_by_region@S92000003", + "name": "ons.population.age_70_79_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 675368.0, + "resolved_value": 519252.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e159eb5144ceae58dccb4dc0" + "resolved_fact_key": "ledger_aggregate_fact_v2_f506930ca553f609fe076c9c" }, { - "name": "ons.population.age_40_49_by_region@N92000002", + "name": "ons.population.age_70_79_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 246140.0, + "resolved_value": 155382.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b71979cb27997e512ea68888" + "resolved_fact_key": "ledger_aggregate_fact_v2_ec559b1c9b44b3acc8de9073" } ] }, - "ons.population.age_50_59_by_region": { + "ons.population.age_80_89_by_region": { "status": "active", "candidates": [ { - "name": "ons.population.age_50_59_by_region@E12000001", + "name": "ons.population.age_80_89_by_region@E12000001", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 360074.0, + "resolved_value": 122118.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8febade5d1aa4eff5515f79" + "resolved_fact_key": "ledger_aggregate_fact_v2_eec7f31aac48f686e0d9a343" }, { - "name": "ons.population.age_50_59_by_region@E12000002", + "name": "ons.population.age_80_89_by_region@E12000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 995810.0, + "resolved_value": 324141.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ce316c567d2d3919bad74247" + "resolved_fact_key": "ledger_aggregate_fact_v2_f5dcf6bfa6186fc6200bb9cd" }, { - "name": "ons.population.age_50_59_by_region@E12000003", + "name": "ons.population.age_80_89_by_region@E12000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 736903.0, + "resolved_value": 243274.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f07e470e70895701083be7b4" + "resolved_fact_key": "ledger_aggregate_fact_v2_ed30948324557f6bd25a0064" }, { - "name": "ons.population.age_50_59_by_region@E12000004", + "name": "ons.population.age_80_89_by_region@E12000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 676307.0, + "resolved_value": 225626.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc3b848c0d546908542f7522" + "resolved_fact_key": "ledger_aggregate_fact_v2_f32be81803e3b527361467e0" }, { - "name": "ons.population.age_50_59_by_region@E12000005", + "name": "ons.population.age_80_89_by_region@E12000005", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 794143.0, + "resolved_value": 275030.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eced9fed4ca113ee655134b7" + "resolved_fact_key": "ledger_aggregate_fact_v2_f252d1b20801bc91a40a9a12" }, { - "name": "ons.population.age_50_59_by_region@E12000006", + "name": "ons.population.age_80_89_by_region@E12000006", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 866946.0, + "resolved_value": 305691.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8011436193a375ac63a33af" + "resolved_fact_key": "ledger_aggregate_fact_v2_d387c1edf10113b2b8602fc3" }, { - "name": "ons.population.age_50_59_by_region@E12000007", + "name": "ons.population.age_80_89_by_region@E12000007", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1087518.0, + "resolved_value": 237061.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c0999183e74a6f6978377427" + "resolved_fact_key": "ledger_aggregate_fact_v2_fa7d5971f83d3ece501a33c7" }, { - "name": "ons.population.age_50_59_by_region@E12000008", + "name": "ons.population.age_80_89_by_region@E12000008", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1287719.0, + "resolved_value": 447958.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5b6740db34f7f702bb230fb" + "resolved_fact_key": "ledger_aggregate_fact_v2_bb61f66f5159481b73615674" }, { - "name": "ons.population.age_50_59_by_region@E12000009", + "name": "ons.population.age_80_89_by_region@E12000009", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 784718.0, + "resolved_value": 313605.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf32f90895454cdb82d3a611" + "resolved_fact_key": "ledger_aggregate_fact_v2_ea5f3461bbda1967761f0d48" }, { - "name": "ons.population.age_50_59_by_region@W92000004", + "name": "ons.population.age_80_89_by_region@W92000004", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 424694.0, + "resolved_value": 154319.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ed905faab304a40013587ffd" + "resolved_fact_key": "ledger_aggregate_fact_v2_d766d2003f1fd56635d53589" }, { - "name": "ons.population.age_50_59_by_region@S92000003", + "name": "ons.population.age_80_89_by_region@S92000003", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 766715.0, + "resolved_value": 238904.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f332e28940d1c94b1e2dec31" + "resolved_fact_key": "ledger_aggregate_fact_v2_f206015a88100a72b83bbe9f" }, { - "name": "ons.population.age_50_59_by_region@N92000002", + "name": "ons.population.age_80_89_by_region@N92000002", "status": "active", "matched_fact_count_overall": 20, "matched_fact_count_at_or_before_period": 20, "geography_level": "country", "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 255269.0, + "resolved_value": 77441.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f786aada1891e9f309902c1c" + "resolved_fact_key": "ledger_aggregate_fact_v2_fb5795d1ea12a7a7005a9ee9" } ] }, - "ons.population.age_60_69_by_region": { + "ons.population.female_0_4": { "status": "active", "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000001", + "name": "ons.population.female_0_4", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 349719.0, + "resolved_value": 1744355.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4466f1cb6fb29ce9b132b0" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_fb55d5f20f74ee39a1e8fcb4" + } + ] + }, + "ons.population.female_10_14": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000002", + "name": "ons.population.female_10_14", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 884043.0, + "resolved_value": 2052052.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f861d328dbb8a01929eb1e91" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_f9a457edc9491e5810c39f5f" + } + ] + }, + "ons.population.female_15_19": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000003", + "name": "ons.population.female_15_19", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 652931.0, + "resolved_value": 2002835.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9ab6846d67db88fda81fa30" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_f0e2139b52c615925c9075dd" + } + ] + }, + "ons.population.female_20_24": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000004", + "name": "ons.population.female_20_24", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 591429.0, + "resolved_value": 2034609.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e884ef403c95938c7ebf961b" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b4e36c0dc0a924667be47bbc" + } + ] + }, + "ons.population.female_25_29": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000005", + "name": "ons.population.female_25_29", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 677922.0, + "resolved_value": 2291610.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd4d62d07376896553d9fb66" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_d9d6a711d0cbc4919a8643c0" + } + ] + }, + "ons.population.female_30_34": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000006", + "name": "ons.population.female_30_34", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2463301.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f5b1d6c400b912b05c79c477" + } + ] + }, + "ons.population.female_35_39": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_35_39", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2472291.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f927cc9b3eab0494caf1479f" + } + ] + }, + "ons.population.female_40_44": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_40_44", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2333109.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d9cdf746ffe5df2fd3d85279" + } + ] + }, + "ons.population.female_45_49": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_45_49", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2088285.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b679e4770750b86af6b1756b" + } + ] + }, + "ons.population.female_50_54": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_50_54", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2255231.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_65b8a4cc92c4565b00007877" + } + ] + }, + "ons.population.female_55_59": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_55_59", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 2360202.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ba87a7d66cb9f8694b952159" + } + ] + }, + "ons.population.female_5_9": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_5_9", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "resolved_period": 2025, + "resolved_value": 1941658.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_bca9c38347810a944bbd08b3" + } + ] + }, + "ons.population.female_60_64": { + "status": "active", + "candidates": [ + { + "name": "ons.population.female_60_64", + "status": "active", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 744651.0, + "resolved_value": 2193915.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f77f96051d8340645148d138" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_f3b1f78e4b752640465521f0" + } + ] + }, + "ons.population.female_65_69": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000007", + "name": "ons.population.female_65_69", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 787666.0, + "resolved_value": 1838574.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e9f63f0939b77a41ec815de0" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_dbeb583b16bcb530ee1296e1" + } + ] + }, + "ons.population.female_70_74": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000008", + "name": "ons.population.female_70_74", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 1089421.0, + "resolved_value": 1622996.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8667b0358441f18c2f8e548" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b962c8b6d3d68808831aad6a" + } + ] + }, + "ons.population.female_75_79": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@E12000009", + "name": "ons.population.female_75_79", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 736639.0, + "resolved_value": 1551183.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f923cb193de625676c40b5c4" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_aa0a8a7ab2d3894db7a7d7aa" + } + ] + }, + "ons.population.female_80_84": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@W92000004", + "name": "ons.population.female_80_84", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 401775.0, + "resolved_value": 1024480.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f518ad65099be8a424a62142" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_fcdc2e2f119de0b65769ef90" + } + ] + }, + "ons.population.female_85_89": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@S92000003", + "name": "ons.population.female_85_89", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 721727.0, + "resolved_value": 665267.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e893656e104d3c1c375fa5e7" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_c76df00751abbf64b5ab056b" + } + ] + }, + "ons.population.female_90_plus": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_60_69_by_region@N92000002", + "name": "ons.population.female_90_plus", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 223111.0, + "resolved_value": 414716.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f6e8f32b460fefc304aeee" + "resolved_fact_key": "ledger_aggregate_fact_v2_009d5dd487f317483e9d7b3d" } ] }, - "ons.population.age_70_79_by_region": { + "ons.population.male_0_4": { "status": "active", "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000001", + "name": "ons.population.male_0_4", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 265573.0, + "resolved_value": 1829801.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f135bc83bf0e2495ccab922b" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ccdfe5dde7b46840510e21d2" + } + ] + }, + "ons.population.male_10_14": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000002", + "name": "ons.population.male_10_14", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 669277.0, + "resolved_value": 2152800.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f18853f5a9046c59334188d3" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_86d603b352e77fd0c03ddaa8" + } + ] + }, + "ons.population.male_15_19": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000003", + "name": "ons.population.male_15_19", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 504131.0, + "resolved_value": 2123750.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f71c0090e322cc6b02a80193" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_ecf390d4b25b71d12aae6bc7" + } + ] + }, + "ons.population.male_20_24": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000004", + "name": "ons.population.male_20_24", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 466530.0, + "resolved_value": 2131646.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1eaa2a27d34d75f4fcaf147" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_edb961b3528b22769eece352" + } + ] + }, + "ons.population.male_25_29": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000005", + "name": "ons.population.male_25_29", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 528207.0, + "resolved_value": 2257360.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f6ed607ecc20a6bd1c0c8bef" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_fd52338de8e1557cdd024c36" + } + ] + }, + "ons.population.male_30_34": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000006", + "name": "ons.population.male_30_34", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 599882.0, + "resolved_value": 2333326.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef2c110c9bb5462379338b17" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b81f56fab808ad1d38d70f3d" + } + ] + }, + "ons.population.male_35_39": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000007", + "name": "ons.population.male_35_39", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 485057.0, + "resolved_value": 2303479.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9b7f415855dd808a1aee77c" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_be9bedc792e0d419ebaf5316" + } + ] + }, + "ons.population.male_40_44": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000008", + "name": "ons.population.male_40_44", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 865392.0, + "resolved_value": 2196013.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dea0c6655095781f862cf7ac" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_d41ff91bfe885debcc12d759" + } + ] + }, + "ons.population.male_45_49": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@E12000009", + "name": "ons.population.male_45_49", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 618254.0, + "resolved_value": 2005099.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8898137aad748593321b2fb" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_fafcbae6e55f9ae20bc0050d" + } + ] + }, + "ons.population.male_50_54": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@W92000004", + "name": "ons.population.male_50_54", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 321668.0, + "resolved_value": 2164862.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1de159eac6f90c69f7aef22" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_b8fe92cfb43b9a95f8a9f7ef" + } + ] + }, + "ons.population.male_55_59": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@S92000003", + "name": "ons.population.male_55_59", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 519252.0, + "resolved_value": 2256521.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f506930ca553f609fe076c9c" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_86b57e4ed1e5186f23dc4021" + } + ] + }, + "ons.population.male_5_9": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_70_79_by_region@N92000002", + "name": "ons.population.male_5_9", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 155382.0, + "resolved_value": 2037199.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ec559b1c9b44b3acc8de9073" + "resolved_fact_key": "ledger_aggregate_fact_v2_e272f955c58535b8b9304759" } ] }, - "ons.population.age_80_89_by_region": { + "ons.population.male_60_64": { "status": "active", "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000001", + "name": "ons.population.male_60_64", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 122118.0, + "resolved_value": 2094462.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_eec7f31aac48f686e0d9a343" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_e60d33e33dcbc1ba2292edf5" + } + ] + }, + "ons.population.male_65_69": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000002", + "name": "ons.population.male_65_69", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 324141.0, + "resolved_value": 1734083.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5dcf6bfa6186fc6200bb9cd" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_a4878efd0023575bded6b67a" + } + ] + }, + "ons.population.male_70_74": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000003", + "name": "ons.population.male_70_74", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 243274.0, + "resolved_value": 1473758.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ed30948324557f6bd25a0064" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_d34aca91f9d1621ea96e72bc" + } + ] + }, + "ons.population.male_75_79": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000004", + "name": "ons.population.male_75_79", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 225626.0, + "resolved_value": 1350668.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f32be81803e3b527361467e0" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_f74158203e735d37a67c5409" + } + ] + }, + "ons.population.male_80_84": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000005", + "name": "ons.population.male_80_84", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 275030.0, + "resolved_value": 815910.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f252d1b20801bc91a40a9a12" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_60aa57af44ada9286df3d649" + } + ] + }, + "ons.population.male_85_89": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000006", + "name": "ons.population.male_85_89", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 305691.0, + "resolved_value": 459511.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d387c1edf10113b2b8602fc3" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_bbfd4e781a7d1151855e4edb" + } + ] + }, + "ons.population.male_90_plus": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000007", + "name": "ons.population.male_90_plus", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 237061.0, + "resolved_value": 210520.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa7d5971f83d3ece501a33c7" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_8ec6d2d034546c9693c4f6ed" + } + ] + }, + "ons.population.scotland_children_under_16": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000008", + "name": "ons.population.scotland_children_under_16", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 32, + "matched_fact_count_at_or_before_period": 32, "resolved_period": 2025, - "resolved_value": 447958.0, + "resolved_value": 896833.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bb61f66f5159481b73615674" - }, + "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" + } + ] + }, + "ons.population.scotland_babies_under_1": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@E12000009", + "name": "ons.population.scotland_babies_under_1", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 313605.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ea5f3461bbda1967761f0d48" - }, + "resolved_value": 46776.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_edd043df0081e63ad0876932" + } + ] + }, + "ons.population.scotland_households_3plus_children": { + "status": "signed_excluded", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@W92000004", + "name": "ons.population.scotland_households_3plus_children", + "status": "signed_excluded", + "matched_fact_count_overall": 552, + "matched_fact_count_at_or_before_period": 552, + "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." + } + ] + }, + "ons.household_composition.lone_households_under_65": { + "status": "active", + "candidates": [ + { + "name": "ons.household_composition.lone_households_under_65", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "W92000004", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 154319.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d766d2003f1fd56635d53589" - }, + "resolved_value": 4316000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b2ee6bff131571b7dcd4c33c" + } + ] + }, + "ons.household_composition.lone_households_over_65": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@S92000003", + "name": "ons.household_composition.lone_households_over_65", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "S92000003", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 238904.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f206015a88100a72b83bbe9f" - }, + "resolved_value": 4254000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4178a72ada0e0b5b53fd62b3" + } + ] + }, + "ons.household_composition.unrelated_adult_households": { + "status": "active", + "candidates": [ { - "name": "ons.population.age_80_89_by_region@N92000002", + "name": "ons.household_composition.unrelated_adult_households", "status": "active", - "matched_fact_count_overall": 20, - "matched_fact_count_at_or_before_period": 20, - "geography_level": "country", - "geography_id": "N92000002", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 77441.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb5795d1ea12a7a7005a9ee9" + "resolved_value": 813000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_191e954854307c61fca2d539" } ] }, - "ons.population.female_0_4": { + "ons.household_composition.couple_no_children_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_0_4", + "name": "ons.household_composition.couple_no_children_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 1744355.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb55d5f20f74ee39a1e8fcb4" + "resolved_value": 8119000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_861314257d00193080069624" } ] }, - "ons.population.female_10_14": { + "ons.household_composition.couple_under_3_children_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_10_14", + "name": "ons.household_composition.couple_under_3_children_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2052052.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9a457edc9491e5810c39f5f" + "resolved_value": 5439000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_04ac3660df720d6f8effbdb2" } ] }, - "ons.population.female_15_19": { + "ons.household_composition.couple_3_plus_children_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_15_19", + "name": "ons.household_composition.couple_3_plus_children_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2002835.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f0e2139b52c615925c9075dd" + "resolved_value": 931000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_3432d322cadb6a40f0c3ebc8" } ] }, - "ons.population.female_20_24": { + "ons.household_composition.couple_non_dependent_children_only_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_20_24", + "name": "ons.household_composition.couple_non_dependent_children_only_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2034609.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b4e36c0dc0a924667be47bbc" + "resolved_value": 1848000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_4d36f952f4dd650bcab7ba7f" } ] }, - "ons.population.female_25_29": { + "ons.household_composition.lone_parent_dependent_children_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_25_29", + "name": "ons.household_composition.lone_parent_dependent_children_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2291610.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9d6a711d0cbc4919a8643c0" + "resolved_value": 1835000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e9746f29548db6f6047842cb" } ] }, - "ons.population.female_30_34": { + "ons.household_composition.lone_parent_non_dependent_children_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_30_34", + "name": "ons.household_composition.lone_parent_non_dependent_children_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2463301.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f5b1d6c400b912b05c79c477" + "resolved_value": 1204000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_9c7f117f90bc24f073f4e14f" } ] }, - "ons.population.female_35_39": { + "ons.household_composition.multi_family_households": { "status": "active", "candidates": [ { - "name": "ons.population.female_35_39", + "name": "ons.household_composition.multi_family_households", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 2472291.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f927cc9b3eab0494caf1479f" + "resolved_value": 244000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_a0cd8874e5334242ce7b8ce0" } ] }, - "ons.population.female_40_44": { + "mhclg.council_tax_stock.band_a": { "status": "active", "candidates": [ { - "name": "ons.population.female_40_44", + "name": "mhclg.council_tax_stock.band_a@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", + "resolved_period": 2025, + "resolved_value": 621096.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_d0152c2791236d6ec749fb4b" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000002", + "status": "active", + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 1285713.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa7c76228b4383e695be0c57" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000003", + "status": "active", + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", + "resolved_period": 2025, + "resolved_value": 988548.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_eb94428708527c6adbce48c3" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000004", + "status": "active", + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", + "resolved_period": 2025, + "resolved_value": 739971.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f17101c03f5970d639ddb6d7" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000005", + "status": "active", + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", + "resolved_period": 2025, + "resolved_value": 728493.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef49e263051486267b93c7cd" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000006", + "status": "active", + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", + "resolved_period": 2025, + "resolved_value": 364482.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9ada16eb0c916b22d2397bb" + }, + { + "name": "mhclg.council_tax_stock.band_a@E12000007", + "status": "active", + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 2333109.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d9cdf746ffe5df2fd3d85279" - } - ] - }, - "ons.population.female_45_49": { - "status": "active", - "candidates": [ + "resolved_value": 118732.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7d8d56243116fa2f1419fe1" + }, { - "name": "ons.population.female_45_49", + "name": "mhclg.council_tax_stock.band_a@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 2088285.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b679e4770750b86af6b1756b" - } - ] - }, - "ons.population.female_50_54": { - "status": "active", - "candidates": [ + "resolved_value": 320025.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fcc7bbe5d78c199fc6d856ca" + }, { - "name": "ons.population.female_50_54", + "name": "mhclg.council_tax_stock.band_a@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 2255231.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_65b8a4cc92c4565b00007877" + "resolved_value": 422969.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f23d41b29d6952c18d44dc26" } ] }, - "ons.population.female_55_59": { + "mhclg.council_tax_stock.band_b": { "status": "active", "candidates": [ { - "name": "ons.population.female_55_59", + "name": "mhclg.council_tax_stock.band_b@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 2360202.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ba87a7d66cb9f8694b952159" - } - ] - }, - "ons.population.female_5_9": { - "status": "active", - "candidates": [ + "resolved_value": 193309.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f84be54967344adf03fab807" + }, { - "name": "ons.population.female_5_9", + "name": "mhclg.council_tax_stock.band_b@E12000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 1941658.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bca9c38347810a944bbd08b3" - } - ] - }, - "ons.population.female_60_64": { - "status": "active", - "candidates": [ + "resolved_value": 666970.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fac49fea11fd3b1110a941c5" + }, { - "name": "ons.population.female_60_64", + "name": "mhclg.council_tax_stock.band_b@E12000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2193915.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f3b1f78e4b752640465521f0" - } - ] - }, - "ons.population.female_65_69": { - "status": "active", - "candidates": [ + "resolved_value": 482052.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8ef63f3e9b07a934c3f2df8" + }, { - "name": "ons.population.female_65_69", + "name": "mhclg.council_tax_stock.band_b@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 1838574.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_dbeb583b16bcb530ee1296e1" - } - ] - }, - "ons.population.female_70_74": { - "status": "active", - "candidates": [ + "resolved_value": 478320.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f48dde558979080156b8c99f" + }, { - "name": "ons.population.female_70_74", + "name": "mhclg.council_tax_stock.band_b@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 1622996.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b962c8b6d3d68808831aad6a" - } - ] - }, - "ons.population.female_75_79": { - "status": "active", - "candidates": [ + "resolved_value": 625673.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fc4a526b4ee56ed620ab4c14" + }, { - "name": "ons.population.female_75_79", + "name": "mhclg.council_tax_stock.band_b@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 1551183.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_aa0a8a7ab2d3894db7a7d7aa" - } - ] - }, - "ons.population.female_80_84": { - "status": "active", - "candidates": [ + "resolved_value": 568914.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe310977523bcaadf025f7f6" + }, { - "name": "ons.population.female_80_84", + "name": "mhclg.council_tax_stock.band_b@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1024480.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcdc2e2f119de0b65769ef90" - } - ] - }, - "ons.population.female_85_89": { - "status": "active", - "candidates": [ + "resolved_value": 463447.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffadb386ab954d99278ba891" + }, { - "name": "ons.population.female_85_89", + "name": "mhclg.council_tax_stock.band_b@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 665267.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c76df00751abbf64b5ab056b" - } - ] - }, - "ons.population.female_90_plus": { - "status": "active", - "candidates": [ + "resolved_value": 649092.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb23fbffbee284d17da76489" + }, { - "name": "ons.population.female_90_plus", + "name": "mhclg.council_tax_stock.band_b@E12000009", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 414716.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_009d5dd487f317483e9d7b3d" + "resolved_value": 609286.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f84a549115340205a9ae8951" } ] }, - "ons.population.male_0_4": { + "mhclg.council_tax_stock.band_c": { "status": "active", "candidates": [ { - "name": "ons.population.male_0_4", + "name": "mhclg.council_tax_stock.band_c@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 1829801.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ccdfe5dde7b46840510e21d2" - } - ] - }, - "ons.population.male_10_14": { - "status": "active", - "candidates": [ + "resolved_value": 186703.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e5eaf3e7f4def06c8d938e5f" + }, + { + "name": "mhclg.council_tax_stock.band_c@E12000002", + "status": "active", + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 585587.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fc2f9b5b1813a71f580f85a4" + }, { - "name": "ons.population.male_10_14", + "name": "mhclg.council_tax_stock.band_c@E12000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2152800.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_86d603b352e77fd0c03ddaa8" - } - ] - }, - "ons.population.male_15_19": { - "status": "active", - "candidates": [ + "resolved_value": 408440.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe416e96e8e324e0e1647008" + }, { - "name": "ons.population.male_15_19", + "name": "mhclg.council_tax_stock.band_c@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2123750.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ecf390d4b25b71d12aae6bc7" - } - ] - }, - "ons.population.male_20_24": { - "status": "active", - "candidates": [ + "resolved_value": 384470.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa1e7c770b7403c2a2663980" + }, { - "name": "ons.population.male_20_24", + "name": "mhclg.council_tax_stock.band_c@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2131646.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edb961b3528b22769eece352" - } - ] - }, - "ons.population.male_25_29": { - "status": "active", - "candidates": [ + "resolved_value": 503657.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ffab2e562cd756fa9f44ac4c" + }, { - "name": "ons.population.male_25_29", + "name": "mhclg.council_tax_stock.band_c@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 2257360.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd52338de8e1557cdd024c36" - } - ] - }, - "ons.population.male_30_34": { - "status": "active", - "candidates": [ + "resolved_value": 708146.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff565a1885420d902566f5be" + }, { - "name": "ons.population.male_30_34", + "name": "mhclg.council_tax_stock.band_c@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 2333326.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b81f56fab808ad1d38d70f3d" - } - ] - }, - "ons.population.male_35_39": { - "status": "active", - "candidates": [ + "resolved_value": 991205.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_eb754d4d8153e7497df94fa9" + }, { - "name": "ons.population.male_35_39", + "name": "mhclg.council_tax_stock.band_c@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 2303479.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_be9bedc792e0d419ebaf5316" - } - ] - }, - "ons.population.male_40_44": { - "status": "active", - "candidates": [ + "resolved_value": 1024169.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_feb50a6c4dfa72419ef9e591" + }, { - "name": "ons.population.male_40_44", + "name": "mhclg.council_tax_stock.band_c@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 2196013.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d41ff91bfe885debcc12d759" + "resolved_value": 587214.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fff7d7ced3067ef09f8e6d12" } ] }, - "ons.population.male_45_49": { + "mhclg.council_tax_stock.band_d": { "status": "active", "candidates": [ { - "name": "ons.population.male_45_49", + "name": "mhclg.council_tax_stock.band_d@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 2005099.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_fafcbae6e55f9ae20bc0050d" - } - ] - }, - "ons.population.male_50_54": { - "status": "active", - "candidates": [ + "resolved_value": 108432.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb2d7a086ad6d3c95a074ab0" + }, { - "name": "ons.population.male_50_54", + "name": "mhclg.council_tax_stock.band_d@E12000002", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 2164862.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b8fe92cfb43b9a95f8a9f7ef" - } - ] - }, - "ons.population.male_55_59": { - "status": "active", - "candidates": [ + "resolved_value": 346489.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff0d7ad8c7d5d0d2f02702f0" + }, { - "name": "ons.population.male_55_59", + "name": "mhclg.council_tax_stock.band_d@E12000003", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 2256521.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_86b57e4ed1e5186f23dc4021" - } - ] - }, - "ons.population.male_5_9": { - "status": "active", - "candidates": [ + "resolved_value": 237496.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7c0b8b92776a6109a114a92" + }, { - "name": "ons.population.male_5_9", + "name": "mhclg.council_tax_stock.band_d@E12000004", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 2037199.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e272f955c58535b8b9304759" - } - ] - }, - "ons.population.male_60_64": { - "status": "active", - "candidates": [ + "resolved_value": 238335.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fa621220d1e5d193343634ca" + }, { - "name": "ons.population.male_60_64", + "name": "mhclg.council_tax_stock.band_d@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 2094462.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_e60d33e33dcbc1ba2292edf5" - } - ] - }, - "ons.population.male_65_69": { - "status": "active", - "candidates": [ + "resolved_value": 288790.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff6f72e91c98eb23dfe9d09c" + }, { - "name": "ons.population.male_65_69", + "name": "mhclg.council_tax_stock.band_d@E12000006", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 1734083.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a4878efd0023575bded6b67a" - } - ] - }, - "ons.population.male_70_74": { - "status": "active", - "candidates": [ + "resolved_value": 485975.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd87126e89fd8a33383640f1" + }, { - "name": "ons.population.male_70_74", + "name": "mhclg.council_tax_stock.band_d@E12000007", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1473758.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d34aca91f9d1621ea96e72bc" - } - ] - }, - "ons.population.male_75_79": { - "status": "active", - "candidates": [ + "resolved_value": 929941.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7dfce8ada24dca8651cdc12" + }, { - "name": "ons.population.male_75_79", + "name": "mhclg.council_tax_stock.band_d@E12000008", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1350668.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f74158203e735d37a67c5409" - } - ] - }, - "ons.population.male_80_84": { - "status": "active", - "candidates": [ + "resolved_value": 807114.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f8129a3bae48724ddc91e4ca" + }, { - "name": "ons.population.male_80_84", + "name": "mhclg.council_tax_stock.band_d@E12000009", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 815910.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_60aa57af44ada9286df3d649" + "resolved_value": 404568.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f3dcc56f346a75bfa16137" } ] }, - "ons.population.male_85_89": { + "mhclg.council_tax_stock.band_e": { "status": "active", "candidates": [ { - "name": "ons.population.male_85_89", + "name": "mhclg.council_tax_stock.band_e@E12000001", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 459511.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_bbfd4e781a7d1151855e4edb" - } - ] - }, - "ons.population.male_90_plus": { - "status": "active", - "candidates": [ + "resolved_value": 58932.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e767a90e1f4f3985379189f5" + }, { - "name": "ons.population.male_90_plus", + "name": "mhclg.council_tax_stock.band_e@E12000002", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 210520.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_8ec6d2d034546c9693c4f6ed" - } - ] - }, - "ons.population.scotland_children_under_16": { - "status": "active", - "candidates": [ + "resolved_value": 207825.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9b8ef4202908453655767f0" + }, { - "name": "ons.population.scotland_children_under_16", + "name": "mhclg.council_tax_stock.band_e@E12000003", "status": "active", - "matched_fact_count_overall": 32, - "matched_fact_count_at_or_before_period": 32, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 896833.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9862176e9cdec891820dfa2" - } - ] - }, - "ons.population.scotland_babies_under_1": { - "status": "active", - "candidates": [ + "resolved_value": 152517.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fbb09c3c4f80ba784375aa37" + }, { - "name": "ons.population.scotland_babies_under_1", + "name": "mhclg.council_tax_stock.band_e@E12000004", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 46776.0, - "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_edd043df0081e63ad0876932" - } - ] - }, - "ons.population.scotland_households_3plus_children": { - "status": "signed_excluded", - "candidates": [ + "resolved_value": 149931.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fec984442b918005ccc92238" + }, { - "name": "ons.population.scotland_households_3plus_children", - "status": "signed_excluded", - "matched_fact_count_overall": 552, - "matched_fact_count_at_or_before_period": 552, - "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." - } - ] - }, - "ons.household_composition.lone_households_under_65": { - "status": "active", - "candidates": [ + "name": "mhclg.council_tax_stock.band_e@E12000005", + "status": "active", + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", + "resolved_period": 2025, + "resolved_value": 185672.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_d83f9067bfa886482b6a5be7" + }, { - "name": "ons.household_composition.lone_households_under_65", + "name": "mhclg.council_tax_stock.band_e@E12000006", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 4316000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b2ee6bff131571b7dcd4c33c" - } - ] - }, - "ons.household_composition.lone_households_over_65": { - "status": "active", - "candidates": [ + "resolved_value": 301723.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb2e48afaa19a026d3d2dbf9" + }, { - "name": "ons.household_composition.lone_households_over_65", + "name": "mhclg.council_tax_stock.band_e@E12000007", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 4254000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4178a72ada0e0b5b53fd62b3" - } - ] - }, - "ons.household_composition.unrelated_adult_households": { - "status": "active", - "candidates": [ + "resolved_value": 551952.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fe53b4ade27bba47669221bb" + }, { - "name": "ons.household_composition.unrelated_adult_households", + "name": "mhclg.council_tax_stock.band_e@E12000008", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 813000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_191e954854307c61fca2d539" - } - ] - }, - "ons.household_composition.couple_no_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 529137.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff8b7b878381855ff02392c8" + }, { - "name": "ons.household_composition.couple_no_children_households", + "name": "mhclg.council_tax_stock.band_e@E12000009", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 8119000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_861314257d00193080069624" + "resolved_value": 274120.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd8affa54b589a8f8dfa76e1" } ] }, - "ons.household_composition.couple_under_3_children_households": { + "mhclg.council_tax_stock.band_f": { "status": "active", "candidates": [ { - "name": "ons.household_composition.couple_under_3_children_households", + "name": "mhclg.council_tax_stock.band_f@E12000001", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 4776, + "matched_fact_count_at_or_before_period": 4728, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 5439000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_04ac3660df720d6f8effbdb2" - } - ] - }, - "ons.household_composition.couple_3_plus_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 25729.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f1a656e56ed4ec922ab1be8a" + }, { - "name": "ons.household_composition.couple_3_plus_children_households", + "name": "mhclg.council_tax_stock.band_f@E12000002", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 931000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_3432d322cadb6a40f0c3ebc8" - } - ] - }, - "ons.household_composition.couple_non_dependent_children_only_households": { - "status": "active", - "candidates": [ + "resolved_value": 100117.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f934ec4447a2decb7d93153c" + }, { - "name": "ons.household_composition.couple_non_dependent_children_only_households", + "name": "mhclg.council_tax_stock.band_f@E12000003", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 5970, + "matched_fact_count_at_or_before_period": 5910, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 1848000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_4d36f952f4dd650bcab7ba7f" - } - ] - }, - "ons.household_composition.lone_parent_dependent_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 73172.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fed1e74402841596ec02537f" + }, { - "name": "ons.household_composition.lone_parent_dependent_children_households", + "name": "mhclg.council_tax_stock.band_f@E12000004", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 13930, + "matched_fact_count_at_or_before_period": 13790, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 1835000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e9746f29548db6f6047842cb" - } - ] - }, - "ons.household_composition.lone_parent_non_dependent_children_households": { - "status": "active", - "candidates": [ + "resolved_value": 71418.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f992d8c87d194b0dfb07b0fa" + }, { - "name": "ons.household_composition.lone_parent_non_dependent_children_households", + "name": "mhclg.council_tax_stock.band_f@E12000005", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 11940, + "matched_fact_count_at_or_before_period": 11820, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 1204000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_9c7f117f90bc24f073f4e14f" - } - ] - }, - "ons.household_composition.multi_family_households": { - "status": "active", - "candidates": [ + "resolved_value": 102077.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9f49f0636d79cb28dcc85e1" + }, { - "name": "ons.household_composition.multi_family_households", + "name": "mhclg.council_tax_stock.band_f@E12000006", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 17910, + "matched_fact_count_at_or_before_period": 17730, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 244000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_a0cd8874e5334242ce7b8ce0" + "resolved_value": 166744.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_e672d9b03691ddd1faac694d" + }, + { + "name": "mhclg.council_tax_stock.band_f@E12000007", + "status": "active", + "matched_fact_count_overall": 13134, + "matched_fact_count_at_or_before_period": 13002, + "geography_level": "region", + "geography_id": "E12000007", + "resolved_period": 2025, + "resolved_value": 279261.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_ef478a0ef6ff0cb78a65dcaa" + }, + { + "name": "mhclg.council_tax_stock.band_f@E12000008", + "status": "active", + "matched_fact_count_overall": 25472, + "matched_fact_count_at_or_before_period": 25216, + "geography_level": "region", + "geography_id": "E12000008", + "resolved_period": 2025, + "resolved_value": 325815.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb02357269b3d262a700cf5f" + }, + { + "name": "mhclg.council_tax_stock.band_f@E12000009", + "status": "active", + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", + "resolved_period": 2025, + "resolved_value": 139412.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fb77e2f50e126802cff79f21" } ] }, - "mhclg.council_tax_stock.band_a": { + "mhclg.council_tax_stock.band_g": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_a@E12000001", + "name": "mhclg.council_tax_stock.band_g@E12000001", "status": "active", "matched_fact_count_overall": 4776, "matched_fact_count_at_or_before_period": 4728, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 621096.0, + "resolved_value": 14062.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d0152c2791236d6ec749fb4b" + "resolved_fact_key": "ledger_aggregate_fact_v2_f80042add7dbd445217cde1a" }, { - "name": "mhclg.council_tax_stock.band_a@E12000002", + "name": "mhclg.council_tax_stock.band_g@E12000002", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 1285713.0, + "resolved_value": 62587.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa7c76228b4383e695be0c57" + "resolved_fact_key": "ledger_aggregate_fact_v2_ffc555374f59e3667468b086" }, { - "name": "mhclg.council_tax_stock.band_a@E12000003", + "name": "mhclg.council_tax_stock.band_g@E12000003", "status": "active", "matched_fact_count_overall": 5970, "matched_fact_count_at_or_before_period": 5910, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 988548.0, + "resolved_value": 40487.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb94428708527c6adbce48c3" + "resolved_fact_key": "ledger_aggregate_fact_v2_f290bf6f13fa468c2acf0be2" }, { - "name": "mhclg.council_tax_stock.band_a@E12000004", + "name": "mhclg.council_tax_stock.band_g@E12000004", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 739971.0, + "resolved_value": 37892.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f17101c03f5970d639ddb6d7" + "resolved_fact_key": "ledger_aggregate_fact_v2_f69d9fecd8d273243af03685" }, { - "name": "mhclg.council_tax_stock.band_a@E12000005", + "name": "mhclg.council_tax_stock.band_g@E12000005", "status": "active", "matched_fact_count_overall": 11940, "matched_fact_count_at_or_before_period": 11820, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 728493.0, + "resolved_value": 60209.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef49e263051486267b93c7cd" + "resolved_fact_key": "ledger_aggregate_fact_v2_ec75efe3a83bc6d9c25d7ae1" }, { - "name": "mhclg.council_tax_stock.band_a@E12000006", + "name": "mhclg.council_tax_stock.band_g@E12000006", "status": "active", "matched_fact_count_overall": 17910, "matched_fact_count_at_or_before_period": 17730, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 364482.0, + "resolved_value": 108700.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9ada16eb0c916b22d2397bb" + "resolved_fact_key": "ledger_aggregate_fact_v2_fd2a0529ed0a7cf9532ef8ea" }, { - "name": "mhclg.council_tax_stock.band_a@E12000007", + "name": "mhclg.council_tax_stock.band_g@E12000007", "status": "active", "matched_fact_count_overall": 13134, "matched_fact_count_at_or_before_period": 13002, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 118732.0, + "resolved_value": 207056.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7d8d56243116fa2f1419fe1" + "resolved_fact_key": "ledger_aggregate_fact_v2_f7d99e8a41825169a450a9ed" }, { - "name": "mhclg.council_tax_stock.band_a@E12000008", + "name": "mhclg.council_tax_stock.band_g@E12000008", "status": "active", "matched_fact_count_overall": 25472, "matched_fact_count_at_or_before_period": 25216, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 320025.0, + "resolved_value": 255206.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fcc7bbe5d78c199fc6d856ca" + "resolved_fact_key": "ledger_aggregate_fact_v2_fda73631af17107d741fed93" }, { - "name": "mhclg.council_tax_stock.band_a@E12000009", + "name": "mhclg.council_tax_stock.band_g@E12000009", "status": "active", "matched_fact_count_overall": 10746, "matched_fact_count_at_or_before_period": 10638, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 422969.0, + "resolved_value": 75533.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f23d41b29d6952c18d44dc26" + "resolved_fact_key": "ledger_aggregate_fact_v2_ddffd3467540ebe8f71dc050" } ] }, - "mhclg.council_tax_stock.band_b": { + "mhclg.council_tax_stock.band_h": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_b@E12000001", + "name": "mhclg.council_tax_stock.band_h@E12000001", "status": "active", "matched_fact_count_overall": 4776, "matched_fact_count_at_or_before_period": 4728, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 193309.0, + "resolved_value": 1151.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f84be54967344adf03fab807" + "resolved_fact_key": "ledger_aggregate_fact_v2_ff4150e637c1d82a68bb2a28" }, { - "name": "mhclg.council_tax_stock.band_b@E12000002", + "name": "mhclg.council_tax_stock.band_h@E12000002", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 666970.0, + "resolved_value": 6230.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fac49fea11fd3b1110a941c5" + "resolved_fact_key": "ledger_aggregate_fact_v2_f742ed87e05f38e0a20ba028" }, { - "name": "mhclg.council_tax_stock.band_b@E12000003", + "name": "mhclg.council_tax_stock.band_h@E12000003", "status": "active", "matched_fact_count_overall": 5970, "matched_fact_count_at_or_before_period": 5910, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 482052.0, + "resolved_value": 3022.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8ef63f3e9b07a934c3f2df8" + "resolved_fact_key": "ledger_aggregate_fact_v2_fd393adec42be55cfefb3400" }, { - "name": "mhclg.council_tax_stock.band_b@E12000004", + "name": "mhclg.council_tax_stock.band_h@E12000004", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 478320.0, + "resolved_value": 2779.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f48dde558979080156b8c99f" + "resolved_fact_key": "ledger_aggregate_fact_v2_fe1b32af9c019b0fa366ea83" }, { - "name": "mhclg.council_tax_stock.band_b@E12000005", + "name": "mhclg.council_tax_stock.band_h@E12000005", "status": "active", "matched_fact_count_overall": 11940, "matched_fact_count_at_or_before_period": 11820, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 625673.0, + "resolved_value": 5285.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc4a526b4ee56ed620ab4c14" + "resolved_fact_key": "ledger_aggregate_fact_v2_f086bebb12518f66fdd27be8" }, { - "name": "mhclg.council_tax_stock.band_b@E12000006", + "name": "mhclg.council_tax_stock.band_h@E12000006", "status": "active", "matched_fact_count_overall": 17910, "matched_fact_count_at_or_before_period": 17730, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 568914.0, + "resolved_value": 13447.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe310977523bcaadf025f7f6" + "resolved_fact_key": "ledger_aggregate_fact_v2_fb031812869aaf579b6d5b62" }, { - "name": "mhclg.council_tax_stock.band_b@E12000007", + "name": "mhclg.council_tax_stock.band_h@E12000007", "status": "active", "matched_fact_count_overall": 13134, "matched_fact_count_at_or_before_period": 13002, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 463447.0, + "resolved_value": 59569.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffadb386ab954d99278ba891" + "resolved_fact_key": "ledger_aggregate_fact_v2_fb5c13d22ffe09151cf3b4f8" }, { - "name": "mhclg.council_tax_stock.band_b@E12000008", + "name": "mhclg.council_tax_stock.band_h@E12000008", "status": "active", "matched_fact_count_overall": 25472, "matched_fact_count_at_or_before_period": 25216, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 649092.0, + "resolved_value": 36978.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb23fbffbee284d17da76489" + "resolved_fact_key": "ledger_aggregate_fact_v2_fd99e21ba622e4f2a978332a" }, { - "name": "mhclg.council_tax_stock.band_b@E12000009", + "name": "mhclg.council_tax_stock.band_h@E12000009", "status": "active", "matched_fact_count_overall": 10746, "matched_fact_count_at_or_before_period": 10638, "geography_level": "region", "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 609286.0, + "resolved_value": 6697.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f84a549115340205a9ae8951" + "resolved_fact_key": "ledger_aggregate_fact_v2_f90a5f109dfd934a167bf0e0" } ] }, - "mhclg.council_tax_stock.band_c": { + "mhclg.council_tax_stock.total": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000001", + "name": "mhclg.council_tax_stock.total@E12000001", "status": "active", "matched_fact_count_overall": 4776, "matched_fact_count_at_or_before_period": 4728, "geography_level": "region", "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 186703.0, + "resolved_value": 1209414.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e5eaf3e7f4def06c8d938e5f" + "resolved_fact_key": "ledger_aggregate_fact_v2_d0495e6e8e02785ad2236142" }, { - "name": "mhclg.council_tax_stock.band_c@E12000002", + "name": "mhclg.council_tax_stock.total@E12000002", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 585587.0, + "resolved_value": 3261518.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc2f9b5b1813a71f580f85a4" + "resolved_fact_key": "ledger_aggregate_fact_v2_fc1af92610b38c4757aea9cd" }, { - "name": "mhclg.council_tax_stock.band_c@E12000003", + "name": "mhclg.council_tax_stock.total@E12000003", "status": "active", "matched_fact_count_overall": 5970, "matched_fact_count_at_or_before_period": 5910, "geography_level": "region", "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 408440.0, + "resolved_value": 2385734.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe416e96e8e324e0e1647008" + "resolved_fact_key": "ledger_aggregate_fact_v2_d97752a94900433af3ad7e6f" }, { - "name": "mhclg.council_tax_stock.band_c@E12000004", + "name": "mhclg.council_tax_stock.total@E12000004", "status": "active", "matched_fact_count_overall": 13930, "matched_fact_count_at_or_before_period": 13790, "geography_level": "region", "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 384470.0, + "resolved_value": 2103116.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa1e7c770b7403c2a2663980" + "resolved_fact_key": "ledger_aggregate_fact_v2_ef350c9b94fb54787fbca592" }, { - "name": "mhclg.council_tax_stock.band_c@E12000005", + "name": "mhclg.council_tax_stock.total@E12000005", "status": "active", "matched_fact_count_overall": 11940, "matched_fact_count_at_or_before_period": 11820, "geography_level": "region", "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 503657.0, + "resolved_value": 2499856.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffab2e562cd756fa9f44ac4c" + "resolved_fact_key": "ledger_aggregate_fact_v2_f649a1ce99478b505d03ab91" }, { - "name": "mhclg.council_tax_stock.band_c@E12000006", + "name": "mhclg.council_tax_stock.total@E12000006", "status": "active", "matched_fact_count_overall": 17910, "matched_fact_count_at_or_before_period": 17730, "geography_level": "region", "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 708146.0, + "resolved_value": 2718131.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff565a1885420d902566f5be" + "resolved_fact_key": "ledger_aggregate_fact_v2_f27b18e8ecc0114a5b9e88e4" }, { - "name": "mhclg.council_tax_stock.band_c@E12000007", + "name": "mhclg.council_tax_stock.total@E12000007", "status": "active", "matched_fact_count_overall": 13134, "matched_fact_count_at_or_before_period": 13002, "geography_level": "region", "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 991205.0, + "resolved_value": 3601163.0, "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_eb754d4d8153e7497df94fa9" + "resolved_fact_key": "ledger_aggregate_fact_v2_f56db6353a3459ee98059504" }, { - "name": "mhclg.council_tax_stock.band_c@E12000008", + "name": "mhclg.council_tax_stock.total@E12000008", "status": "active", "matched_fact_count_overall": 25472, "matched_fact_count_at_or_before_period": 25216, "geography_level": "region", "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 1024169.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_feb50a6c4dfa72419ef9e591" - }, + "resolved_value": 3947536.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_fd4beff6e5a58b2ca5ff0b3a" + }, + { + "name": "mhclg.council_tax_stock.total@E12000009", + "status": "active", + "matched_fact_count_overall": 10746, + "matched_fact_count_at_or_before_period": 10638, + "geography_level": "region", + "geography_id": "E12000009", + "resolved_period": 2025, + "resolved_value": 2519799.0, + "resolved_fact_period": "2025-10", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7339b440103ee7084920ea3" + } + ] + }, + "welshgov.council_tax_stock.band_a": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_a", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 194973.29, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_21e317eb3f397169fa2dc933" + } + ] + }, + "welshgov.council_tax_stock.band_b": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_b", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 285787.52, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_1db23c3de870c2f9704b9822" + } + ] + }, + "welshgov.council_tax_stock.band_c": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_c", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 301699.86, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_c8c0495e5862c06f0f268414" + } + ] + }, + "welshgov.council_tax_stock.band_d": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_d", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 225179.88, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_04e498c0e2dad39004885ea3" + } + ] + }, + "welshgov.council_tax_stock.band_e": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_e", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 185447.46, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_e8ca0bef4217724c1b6eafbb" + } + ] + }, + "welshgov.council_tax_stock.band_f": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_f", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 114672.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_f9e314273b8264de7d24a7b6" + } + ] + }, + "welshgov.council_tax_stock.band_g": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_g", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 52211.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_1ffc03853a7f22dbfdfd30ee" + } + ] + }, + "welshgov.council_tax_stock.band_h": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_h", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 12357.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_38b37ca6c167d44f1ee2b517" + } + ] + }, + "welshgov.council_tax_stock.band_i": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.band_i", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 5305.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_f94d0825d8f1f21a02667aeb" + } + ] + }, + "welshgov.council_tax_stock.total": { + "status": "active", + "candidates": [ + { + "name": "welshgov.council_tax_stock.total", + "status": "active", + "matched_fact_count_overall": 436, + "matched_fact_count_at_or_before_period": 339, + "resolved_period": 2025, + "resolved_value": 1377633.03, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_69899dbf797a73ce0c05f13d" + } + ] + }, + "scotgov.council_tax_stock.band_a": { + "status": "active", + "candidates": [ + { + "name": "scotgov.council_tax_stock.band_a", + "status": "active", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, + "resolved_period": 2025, + "resolved_value": 498707.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_d16c53fe6a1c8f4f5886b7e5" + } + ] + }, + "scotgov.council_tax_stock.band_b": { + "status": "active", + "candidates": [ + { + "name": "scotgov.council_tax_stock.band_b", + "status": "active", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, + "resolved_period": 2025, + "resolved_value": 583705.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_2f95ec98ae61f9898bd47ed9" + } + ] + }, + "scotgov.council_tax_stock.band_c": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_c@E12000009", + "name": "scotgov.council_tax_stock.band_c", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 587214.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fff7d7ced3067ef09f8e6d12" + "resolved_value": 426388.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_c9781708df55dc5d197e6623" } ] }, - "mhclg.council_tax_stock.band_d": { + "scotgov.council_tax_stock.band_d": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000001", + "name": "scotgov.council_tax_stock.band_d", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 108432.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb2d7a086ad6d3c95a074ab0" - }, + "resolved_value": 369621.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_ae1fe03809a505b820479598" + } + ] + }, + "scotgov.council_tax_stock.band_e": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000002", + "name": "scotgov.council_tax_stock.band_e", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 346489.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff0d7ad8c7d5d0d2f02702f0" - }, + "resolved_value": 366881.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_e83153e0de40fb74471c805f" + } + ] + }, + "scotgov.council_tax_stock.band_f": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000003", + "name": "scotgov.council_tax_stock.band_f", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 237496.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7c0b8b92776a6109a114a92" - }, + "resolved_value": 221282.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_b24b6409c1473600c03999ec" + } + ] + }, + "scotgov.council_tax_stock.band_g": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000004", + "name": "scotgov.council_tax_stock.band_g", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 238335.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fa621220d1e5d193343634ca" - }, + "resolved_value": 142084.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_c86494a855b00998122989d6" + } + ] + }, + "scotgov.council_tax_stock.band_h": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000005", + "name": "scotgov.council_tax_stock.band_h", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 288790.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff6f72e91c98eb23dfe9d09c" - }, + "resolved_value": 14481.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_60d9ae638eff29fc1c88907e" + } + ] + }, + "scotgov.council_tax_stock.total": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000006", + "name": "scotgov.council_tax_stock.total", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 485975.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd87126e89fd8a33383640f1" - }, + "resolved_value": 2623149.0, + "resolved_fact_period": "2025-09", + "resolved_fact_key": "ledger_aggregate_fact_v2_ca77a0f0a777ccba05e4bef9" + } + ] + }, + "scotgov.scottish_child_payment_spending": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000007", + "name": "scotgov.scottish_child_payment_spending", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 929941.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7dfce8ada24dca8651cdc12" - }, + "resolved_value": 471000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_20b43b0f8f61e448f28895cf" + } + ] + }, + "ons.savings_interest_income": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000008", + "name": "ons.savings_interest_income", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 8, + "matched_fact_count_at_or_before_period": 8, "resolved_period": 2025, - "resolved_value": 807114.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f8129a3bae48724ddc91e4ca" - }, + "resolved_value": 95503000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_8de1806d1330bcb80a1f4988" + } + ] + }, + "ons.public_sector_employment": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_d@E12000009", + "name": "ons.public_sector_employment", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 404568.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f3dcc56f346a75bfa16137" + "resolved_value": 6146000.0, + "resolved_fact_period": "2024-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff79b4e2301f564ec4203235" } ] }, - "mhclg.council_tax_stock.band_e": { + "ons.land.land_value": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000001", + "name": "ons.land.land_value", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 58932.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e767a90e1f4f3985379189f5" - }, + "resolved_value": 7117771000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_4daf8d1b8830f72bba924d56" + } + ] + }, + "ons.land.household_land_value": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000002", + "name": "ons.land.household_land_value", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 207825.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9b8ef4202908453655767f0" - }, + "resolved_value": 4559831000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_0e5f9867ab377dffd8a8941f" + } + ] + }, + "ons.land.corporate_land_value": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000003", + "name": "ons.land.corporate_land_value", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 30, + "matched_fact_count_at_or_before_period": 30, "resolved_period": 2025, - "resolved_value": 152517.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fbb09c3c4f80ba784375aa37" - }, + "resolved_value": 2103053000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ab561a17be0af52de30cca88" + } + ] + }, + "slc.repayments.devolved_total": { + "status": "no_fact_at_or_before_period", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000004", + "name": "slc.repayments.devolved_total", + "status": "no_fact_at_or_before_period", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "error": "ledger_reference_compile_status_no_fact_at_or_before_period" + } + ] + }, + "slc.repayments.england_total_higher_education": { + "status": "active", + "candidates": [ + { + "name": "slc.repayments.england_total_higher_education", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 149931.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fec984442b918005ccc92238" - }, + "resolved_value": 5018231834.949999, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b947d1f3c3659d252194c102" + } + ] + }, + "slc.repayments.england_plan_1": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000005", + "name": "slc.repayments.england_plan_1", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 185672.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d83f9067bfa886482b6a5be7" - }, + "resolved_value": 1852699178.55, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_1d9680e6eaf243227fed5ef2" + } + ] + }, + "slc.repayments.england_plan_2": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000006", + "name": "slc.repayments.england_plan_2", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 301723.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb2e48afaa19a026d3d2dbf9" - }, + "resolved_value": 2778253361.64, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_882329821c90dc683aa778d8" + } + ] + }, + "slc.repayments.england_postgraduate": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000007", + "name": "slc.repayments.england_postgraduate", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 551952.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe53b4ade27bba47669221bb" - }, + "resolved_value": 346409713.95000005, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ac1b07c69f1e1baa2a0fb787" + } + ] + }, + "slc.repayments.england_plan_5": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000008", + "name": "slc.repayments.england_plan_5", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 529137.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff8b7b878381855ff02392c8" - }, + "resolved_value": 40869580.81, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_496af6b8fe31c71c43f1d292" + } + ] + }, + "slc.borrowers.plan_2_above_threshold": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_e@E12000009", + "name": "slc.borrowers.plan_2_above_threshold", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 274120.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd8affa54b589a8f8dfa76e1" + "resolved_value": 4460000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_02288c19caeae900fdaf1e0d" } ] }, - "mhclg.council_tax_stock.band_f": { + "slc.borrowers.plan_2_liable": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000001", + "name": "slc.borrowers.plan_2_liable", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 25729.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f1a656e56ed4ec922ab1be8a" - }, + "resolved_value": 9710000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_37387933e73bcc8c1e04cf78" + } + ] + }, + "slc.borrowers.plan_5_above_threshold": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000002", + "name": "slc.borrowers.plan_5_above_threshold", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 100117.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f934ec4447a2decb7d93153c" - }, + "resolved_value": 35000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_dd16b085f81ef7708a00511e" + } + ] + }, + "slc.borrowers.plan_5_liable": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000003", + "name": "slc.borrowers.plan_5_liable", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 73172.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fed1e74402841596ec02537f" - }, + "resolved_value": 230000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_73ff136d820950ea404ddb6b" + } + ] + }, + "slc.support.maintenance_loan_recipients": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000004", + "name": "slc.support.maintenance_loan_recipients", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 71418.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f992d8c87d194b0dfb07b0fa" - }, + "resolved_value": 1159761.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f03bd7a10d0eee9917a3a199" + } + ] + }, + "slc.support.maintenance_loan_spend": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000005", + "name": "slc.support.maintenance_loan_spend", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 102077.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9f49f0636d79cb28dcc85e1" - }, + "resolved_value": 8591659718.080004, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_2900e25d7ee90f79fb3b87b9" + } + ] + }, + "slc.support.parents_learning_allowance_recipients": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000006", + "name": "slc.support.parents_learning_allowance_recipients", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 166744.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_e672d9b03691ddd1faac694d" - }, + "resolved_value": 99645.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d5df1c69846ab2fd3d0e50e1" + } + ] + }, + "slc.support.parents_learning_allowance_spend": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000007", + "name": "slc.support.parents_learning_allowance_spend", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 279261.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef478a0ef6ff0cb78a65dcaa" - }, + "resolved_value": 181421659.32, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_72028ce00b9569deec79d6e6" + } + ] + }, + "slc.support.adult_dependants_grant_recipients": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000008", + "name": "slc.support.adult_dependants_grant_recipients", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 325815.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb02357269b3d262a700cf5f" - }, + "resolved_value": 18611.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_adc83b5d137ecb48fed77064" + } + ] + }, + "slc.support.adult_dependants_grant_spend": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_f@E12000009", + "name": "slc.support.adult_dependants_grant_spend", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 139412.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb77e2f50e126802cff79f21" + "resolved_value": 55364916.81, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_5d42660596c9088248e41e90" } ] }, - "mhclg.council_tax_stock.band_g": { + "dwp.uc.households": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000001", + "name": "dwp.uc.households", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 120, + "matched_fact_count_at_or_before_period": 120, + "matched_fact_count_in_source_window": 120, "resolved_period": 2025, - "resolved_value": 14062.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f80042add7dbd445217cde1a" - }, + "resolved_value": 6197311.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_71c060f3f2a732e2f836a5d8" + } + ] + }, + "hmrc.tfc.government_top_up": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000002", + "name": "hmrc.tfc.government_top_up", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 9, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 62587.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ffc555374f59e3667468b086" - }, + "resolved_value": 599800000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_988715985f9e98bbb332e83d" + } + ] + }, + "hmrc.tfc.children_with_used_accounts": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000003", + "name": "hmrc.tfc.children_with_used_accounts", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 40487.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f290bf6f13fa468c2acf0be2" - }, + "resolved_value": 1151515.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_7aa1c663447037b35ea1c999" + } + ] + }, + "dfe.funded_childcare.working_parent_children_2_to_4": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000004", + "name": "dfe.funded_childcare.working_parent_children_2_to_4", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 11, + "matched_fact_count_at_or_before_period": 9, "resolved_period": 2025, - "resolved_value": 37892.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f69d9fecd8d273243af03685" - }, + "resolved_value": 621482.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_a57a0c03ac43b62dde04fabd" + } + ] + }, + "dfe.funded_childcare.early_learning_2_year_olds": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000005", + "name": "dfe.funded_childcare.early_learning_2_year_olds", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 11, "resolved_period": 2025, - "resolved_value": 60209.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ec75efe3a83bc6d9c25d7ae1" - }, + "resolved_value": 95031.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_a2b30af28303935159ba0edc" + } + ] + }, + "dfe.funded_childcare.universal_only_children": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000006", + "name": "dfe.funded_childcare.universal_only_children", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 770, + "matched_fact_count_at_or_before_period": 686, "resolved_period": 2025, - "resolved_value": 108700.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd2a0529ed0a7cf9532ef8ea" - }, + "resolved_value": 396965.0, + "resolved_fact_period": "2025-01", + "resolved_fact_key": "ledger_aggregate_fact_v2_471573def13ebdc67ff1f40a" + } + ] + }, + "dft.bus_fare_receipts.england": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000007", + "name": "dft.bus_fare_receipts.england", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 207056.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7d99e8a41825169a450a9ed" - }, + "resolved_value": 3612036036.2194014, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_2ece7c3d283b6de43b30389f", + "uprating": { + "index": "dft.local_bus_fares_index", + "factor": "1.05695792880259", + "value_before_uprating": "3417388656.43538" + } + } + ] + }, + "dft.bus_net_support.england": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000008", + "name": "dft.bus_net_support.england", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 255206.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fda73631af17107d741fed93" - }, + "resolved_value": 3024904320.8399997, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a12dfcdc0662c8a5e48bf003" + } + ] + }, + "dft.bus_fare_receipts.london": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_g@E12000009", + "name": "dft.bus_fare_receipts.london", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 75533.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ddffd3467540ebe8f71dc050" + "resolved_value": 1347434943.01459, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_33611c64d2048fe660501802", + "uprating": { + "index": "dft.local_bus_fares_index", + "factor": "1", + "value_before_uprating": "1347434943.01459" + } } ] }, - "mhclg.council_tax_stock.band_h": { + "dft.bus_net_support.london": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000001", + "name": "dft.bus_net_support.london", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 3, + "matched_fact_count_at_or_before_period": 3, "resolved_period": 2025, - "resolved_value": 1151.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff4150e637c1d82a68bb2a28" - }, + "resolved_value": 1130214000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d8e40cee2fc723b719ff4680" + } + ] + }, + "dft.bus_fare_receipts.england_outside_london": { + "status": "signed_excluded", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000002", - "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", - "resolved_period": 2025, - "resolved_value": 6230.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f742ed87e05f38e0a20ba028" - }, + "name": "dft.bus_fare_receipts.england_outside_london", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." + } + ] + }, + "dft.bus_net_support.england_outside_london": { + "status": "signed_excluded", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000003", - "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", - "resolved_period": 2025, - "resolved_value": 3022.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd393adec42be55cfefb3400" - }, + "name": "dft.bus_net_support.england_outside_london", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." + } + ] + }, + "dft.bus_fare_receipts.uk": { + "status": "signed_excluded", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000004", - "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", - "resolved_period": 2025, - "resolved_value": 2779.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fe1b32af9c019b0fa366ea83" - }, + "name": "dft.bus_fare_receipts.uk", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "BUS05i publishes no UK total and Microcosm declares no method to construct one." + } + ] + }, + "dft.bus_net_support.uk": { + "status": "signed_excluded", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000005", - "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", - "resolved_period": 2025, - "resolved_value": 5285.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f086bebb12518f66fdd27be8" - }, + "name": "dft.bus_net_support.uk", + "status": "signed_excluded", + "matched_fact_count_overall": 0, + "matched_fact_count_at_or_before_period": 0, + "signed_rationale": "BUS05i publishes no UK total and no England-to-UK uplift is declared. Net support binds instead as four country legs whose scopes differ: DfT BUS05bi net support (England, operators' view), Scottish Transport Statistics all government support (Scotland), StatsWales revenue outturn gross expenditure on concessionary fares and support to operators through local authorities only (Wales: no operator-side series and no Welsh Government grants outside the outturn), and the NITHC accounts' Public Service Obligation plus concessionary compensation as one bus-plus-rail cell excluding GBP 53.2m of other revenue funding (Northern Ireland). The legs are bound on their own terms; they are not a UK total under another name." + } + ] + }, + "obr.fuel_duties_cars": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000006", + "name": "obr.fuel_duties_cars", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 13447.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb031812869aaf579b6d5b62" - }, + "resolved_value": 14400000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_de6554fe8ab7b481035a432a" + } + ] + }, + "orr.rail_government_support": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000007", + "name": "orr.rail_government_support", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, "resolved_period": 2025, - "resolved_value": 59569.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fb5c13d22ffe09151cf3b4f8" - }, + "resolved_value": 21621100549.34064, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_b16b9b3f2329455f907f9ccc" + } + ] + }, + "ons.household_energy_expenditure": { + "status": "signed_excluded", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000008", - "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", - "resolved_period": 2025, - "resolved_value": 36978.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd99e21ba622e4f2a978332a" - }, + "name": "ons.household_energy_expenditure", + "status": "signed_excluded", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, + "signed_rationale": "ONS Consumer Trends COICOP 04.5 (electricity, gas and other fuels) carries liquid and solid fuels the frame does not model; chronicle #271 (chronicle#270) published the 04.5.1 electricity and 04.5.2 gas sub-classes, which ons.household_electricity_expenditure and ons.household_gas_expenditure bind per fuel on the frame's own columns. The total row is retained in the contract for registry parity and signed out here (microcosm#890 F1)." + } + ] + }, + "ons.household_electricity_expenditure": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.band_h@E12000009", + "name": "ons.household_electricity_expenditure", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 6697.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f90a5f109dfd934a167bf0e0" + "resolved_value": 26522000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_69cd660b943ae8f21761f76a" } ] }, - "mhclg.council_tax_stock.total": { + "ons.household_gas_expenditure": { "status": "active", "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000001", + "name": "ons.household_gas_expenditure", "status": "active", - "matched_fact_count_overall": 4776, - "matched_fact_count_at_or_before_period": 4728, - "geography_level": "region", - "geography_id": "E12000001", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 1209414.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d0495e6e8e02785ad2236142" - }, + "resolved_value": 15339000000.0, + "resolved_fact_period": "2025", + "resolved_fact_key": "ledger_aggregate_fact_v2_b56be49c552300f6c02fc559" + } + ] + }, + "scotgov.bus.passenger_revenue": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000002", + "name": "scotgov.bus.passenger_revenue", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000002", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3261518.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fc1af92610b38c4757aea9cd" - }, + "resolved_value": 391000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c4269bb83534f1e46f5801c1" + } + ] + }, + "scotgov.bus.government_support": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000003", + "name": "scotgov.bus.government_support", "status": "active", - "matched_fact_count_overall": 5970, - "matched_fact_count_at_or_before_period": 5910, - "geography_level": "region", - "geography_id": "E12000003", + "matched_fact_count_overall": 2, + "matched_fact_count_at_or_before_period": 2, "resolved_period": 2025, - "resolved_value": 2385734.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_d97752a94900433af3ad7e6f" - }, + "resolved_value": 499000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ceb60fd41d0f5587be94c234" + } + ] + }, + "welshgov.bus.public_support": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000004", + "name": "welshgov.bus.public_support", "status": "active", - "matched_fact_count_overall": 13930, - "matched_fact_count_at_or_before_period": 13790, - "geography_level": "region", - "geography_id": "E12000004", + "matched_fact_count_overall": 6, + "matched_fact_count_at_or_before_period": 6, "resolved_period": 2025, - "resolved_value": 2103116.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_ef350c9b94fb54787fbca592" - }, + "resolved_value": 131489970.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a10fcfec7cb458fa0c8c7f10" + } + ] + }, + "dfi_ni.bus.passenger_receipts": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000005", + "name": "dfi_ni.bus.passenger_receipts", "status": "active", - "matched_fact_count_overall": 11940, - "matched_fact_count_at_or_before_period": 11820, - "geography_level": "region", - "geography_id": "E12000005", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, "resolved_period": 2025, - "resolved_value": 2499856.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f649a1ce99478b505d03ab91" - }, + "resolved_value": 150082817.48999995, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_96f72989614e0c5faaeeabbb" + } + ] + }, + "nithc.public_transport_support": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000006", + "name": "nithc.public_transport_support", "status": "active", - "matched_fact_count_overall": 17910, - "matched_fact_count_at_or_before_period": 17730, - "geography_level": "region", - "geography_id": "E12000006", + "matched_fact_count_overall": 4, + "matched_fact_count_at_or_before_period": 4, "resolved_period": 2025, - "resolved_value": 2718131.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f27b18e8ecc0114a5b9e88e4" - }, + "resolved_value": 111700000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_be8eb7011b6f65fa65d52fcb" + } + ] + }, + "dwp.uc.households_lcwra_element": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000007", + "name": "dwp.uc.households_lcwra_element", "status": "active", - "matched_fact_count_overall": 13134, - "matched_fact_count_at_or_before_period": 13002, - "geography_level": "region", - "geography_id": "E12000007", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 3601163.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f56db6353a3459ee98059504" - }, + "resolved_value": 2272425.1666666665, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f59149c4c514e1acffb728a8" + } + ] + }, + "dwp.uc.households_carer_element": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000008", + "name": "dwp.uc.households_carer_element", "status": "active", - "matched_fact_count_overall": 25472, - "matched_fact_count_at_or_before_period": 25216, - "geography_level": "region", - "geography_id": "E12000008", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 3947536.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_fd4beff6e5a58b2ca5ff0b3a" - }, + "resolved_value": 1078514.5, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_d56ddfa58d7ebb3ff0178b0a" + } + ] + }, + "dwp.uc.households_housing_element": { + "status": "active", + "candidates": [ { - "name": "mhclg.council_tax_stock.total@E12000009", + "name": "dwp.uc.households_housing_element", "status": "active", - "matched_fact_count_overall": 10746, - "matched_fact_count_at_or_before_period": 10638, - "geography_level": "region", - "geography_id": "E12000009", + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 2519799.0, - "resolved_fact_period": "2025-10", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7339b440103ee7084920ea3" + "resolved_value": 4037650.3333333335, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_04b7ec6d195e6682f0421672" } ] }, - "welshgov.council_tax_stock.band_a": { + "dwp.uc.households_housing_element_social_rented": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_a", + "name": "dwp.uc.households_housing_element_social_rented", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 194973.29, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_21e317eb3f397169fa2dc933" + "resolved_value": 2354587.5833333335, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_109598f6aaa42fe1387d30d1" } ] }, - "welshgov.council_tax_stock.band_b": { + "dwp.uc.households_housing_element_private_rented": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_b", + "name": "dwp.uc.households_housing_element_private_rented", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 285787.52, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_1db23c3de870c2f9704b9822" + "resolved_value": 1570545.4166666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_7a31b88dfcd4b3d0c758a1c3" } ] }, - "welshgov.council_tax_stock.band_c": { + "dwp.uc.households_childcare_element": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_c", + "name": "dwp.uc.households_childcare_element", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 301699.86, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_c8c0495e5862c06f0f268414" + "resolved_value": 178666.66666666666, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_0c1aa0cc56d86c50d6b2560a" } ] }, - "welshgov.council_tax_stock.band_d": { + "dwp.uc.households_with_deduction": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_d", + "name": "dwp.uc.households_with_deduction", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 10, + "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_in_source_window": 10, "resolved_period": 2025, - "resolved_value": 225179.88, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_04e498c0e2dad39004885ea3" + "resolved_value": 3130000.0, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f7bfdb41a462c417535602d2" } ] }, - "welshgov.council_tax_stock.band_e": { + "obr.universal_credit": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_e", + "name": "obr.universal_credit", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 14, + "matched_fact_count_at_or_before_period": 4, "resolved_period": 2025, - "resolved_value": 185447.46, + "resolved_value": 79286349139.54411, "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e8ca0bef4217724c1b6eafbb" + "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" } ] }, - "welshgov.council_tax_stock.band_f": { + "dwp.hb.households": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_f", + "name": "dwp.hb.households", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 114672.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_f9e314273b8264de7d24a7b6" + "resolved_value": 1685702.9166666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_f2ecf4d38ef4dfc796336538" } ] }, - "welshgov.council_tax_stock.band_g": { + "dwp.hb.households_social_rented": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_g", + "name": "dwp.hb.households_social_rented", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 52211.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_1ffc03853a7f22dbfdfd30ee" + "resolved_value": 1381089.75, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_40b45c74a40b8d085a8c28e2" } ] }, - "welshgov.council_tax_stock.band_h": { + "dwp.hb.households_private_rented": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_h", + "name": "dwp.hb.households_private_rented", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 12, + "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_in_source_window": 12, "resolved_period": 2025, - "resolved_value": 12357.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_38b37ca6c167d44f1ee2b517" + "resolved_value": 304422.6666666667, + "resolved_fact_period": "2025-12", + "resolved_fact_key": "ledger_aggregate_fact_v2_02281858b7b0d71477e429f3" } ] }, - "welshgov.council_tax_stock.band_i": { + "dwp.benefit_cap.capped_households_up_to_100": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.band_i", + "name": "dwp.benefit_cap.capped_households_up_to_100", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5305.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_f94d0825d8f1f21a02667aeb" + "resolved_value": 38402.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_220b82ab05bec494e6dc9fe9" } ] }, - "welshgov.council_tax_stock.total": { + "dwp.benefit_cap.capped_households_100_01_to_200": { "status": "active", "candidates": [ { - "name": "welshgov.council_tax_stock.total", + "name": "dwp.benefit_cap.capped_households_100_01_to_200", "status": "active", - "matched_fact_count_overall": 436, - "matched_fact_count_at_or_before_period": 339, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1377633.03, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_69899dbf797a73ce0c05f13d" + "resolved_value": 24274.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_4a9e2cc181aee62e1eccd188" } ] }, - "scotgov.council_tax_stock.band_a": { + "dwp.benefit_cap.capped_households_200_01_to_300": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_a", + "name": "dwp.benefit_cap.capped_households_200_01_to_300", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 498707.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_d16c53fe6a1c8f4f5886b7e5" + "resolved_value": 16240.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_5ae8289242eabcffab23f32f" } ] }, - "scotgov.council_tax_stock.band_b": { + "dwp.benefit_cap.capped_households_300_01_to_400": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_b", + "name": "dwp.benefit_cap.capped_households_300_01_to_400", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 583705.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_2f95ec98ae61f9898bd47ed9" + "resolved_value": 10562.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_a503d4e938aaf386720b96c4" } ] }, - "scotgov.council_tax_stock.band_c": { + "dwp.benefit_cap.capped_households_400_01_to_500": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_c", + "name": "dwp.benefit_cap.capped_households_400_01_to_500", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 426388.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_c9781708df55dc5d197e6623" + "resolved_value": 7813.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_df764409769b2078c69ff113" } ] }, - "scotgov.council_tax_stock.band_d": { + "dwp.benefit_cap.capped_households_500_01_to_600": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_d", + "name": "dwp.benefit_cap.capped_households_500_01_to_600", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 369621.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_ae1fe03809a505b820479598" + "resolved_value": 4431.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_3d0e936b240ba62209777ee3" } ] }, - "scotgov.council_tax_stock.band_e": { + "dwp.benefit_cap.capped_households_600_01_to_700": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_e", + "name": "dwp.benefit_cap.capped_households_600_01_to_700", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 366881.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_e83153e0de40fb74471c805f" + "resolved_value": 3116.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_1d68398dd88958a8700dcfac" } ] }, - "scotgov.council_tax_stock.band_f": { + "dwp.benefit_cap.capped_households_700_01_to_800": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_f", + "name": "dwp.benefit_cap.capped_households_700_01_to_800", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 221282.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_b24b6409c1473600c03999ec" + "resolved_value": 1902.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_999288b0fa67d7f657810a11" } ] }, - "scotgov.council_tax_stock.band_g": { + "dwp.benefit_cap.capped_households_800_01_to_900": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_g", + "name": "dwp.benefit_cap.capped_households_800_01_to_900", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 142084.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_c86494a855b00998122989d6" + "resolved_value": 1328.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_b7a2d0cec131abfd0cb81ba0" } ] }, - "scotgov.council_tax_stock.band_h": { + "dwp.benefit_cap.capped_households_900_01_to_1000": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.band_h", + "name": "dwp.benefit_cap.capped_households_900_01_to_1000", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 14481.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_60d9ae638eff29fc1c88907e" + "resolved_value": 824.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_80c8fa82f3e07357e677ae93" } ] }, - "scotgov.council_tax_stock.total": { + "dwp.benefit_cap.capped_households_1000_01_to_1100": { "status": "active", "candidates": [ { - "name": "scotgov.council_tax_stock.total", + "name": "dwp.benefit_cap.capped_households_1000_01_to_1100", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2623149.0, - "resolved_fact_period": "2025-09", - "resolved_fact_key": "ledger_aggregate_fact_v2_ca77a0f0a777ccba05e4bef9" + "resolved_value": 497.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_cf55cee33404d2283800b2b5" } ] }, - "scotgov.scottish_child_payment_spending": { + "dwp.benefit_cap.capped_households_1100_01_to_1200": { "status": "active", "candidates": [ { - "name": "scotgov.scottish_child_payment_spending", + "name": "dwp.benefit_cap.capped_households_1100_01_to_1200", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 471000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_20b43b0f8f61e448f28895cf" + "resolved_value": 380.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_6f836a33391f4352151bd27f" } ] }, - "ons.savings_interest_income": { + "dwp.benefit_cap.capped_households_1200_01_to_1300": { "status": "active", "candidates": [ { - "name": "ons.savings_interest_income", + "name": "dwp.benefit_cap.capped_households_1200_01_to_1300", "status": "active", - "matched_fact_count_overall": 8, - "matched_fact_count_at_or_before_period": 8, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 95503000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_8de1806d1330bcb80a1f4988" + "resolved_value": 239.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_ad08714cf39be9ccf0450cf2" } ] }, - "ons.public_sector_employment": { + "dwp.benefit_cap.capped_households_1300_01_and_above": { "status": "active", "candidates": [ { - "name": "ons.public_sector_employment", + "name": "dwp.benefit_cap.capped_households_1300_01_and_above", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 6146000.0, - "resolved_fact_period": "2024-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_ff79b4e2301f564ec4203235" + "resolved_value": 627.0, + "resolved_fact_period": "2025-11", + "resolved_fact_key": "ledger_aggregate_fact_v2_a3fee6cdec1b46a15a3b1434" } ] }, - "ons.land.land_value": { + "hmrc.cgt.taxpayers_by_age_band": { "status": "active", "candidates": [ { - "name": "ons.land.land_value", + "name": "hmrc.cgt.taxpayers_by_age_band.age_0_to_15", + "status": "signed_excluded", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "signed_row": { + "dimension": "age_band", + "value": "age_0_to_15" + }, + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_16_to_24", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 4000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_8c3d294de4cbdbe292815164" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_25_to_34", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 27000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_cc8ef619f52f7f44a885ce52" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_35_to_44", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 65000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_8554e7f842699a5f49816a0d" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_45_to_54", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 98000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_794376b60fba0684412fdff8" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_55_to_64", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 144000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_0d6b6c36290ab598f74f6669" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_65_to_74", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 125000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a725972fe4ee87a3bddee1cf" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_75_to_84", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 68000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_1e4899d950c2b2be8ae21459" + }, + { + "name": "hmrc.cgt.taxpayers_by_age_band.age_85_plus", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7117771000000.0, + "resolved_value": 19000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_4daf8d1b8830f72bba924d56" + "resolved_fact_key": "ledger_aggregate_fact_v2_7c419e2a82d25fae0127fd1d" } ] }, - "ons.land.household_land_value": { + "hmrc.cgt.gains_by_age_band": { "status": "active", "candidates": [ { - "name": "ons.land.household_land_value", + "name": "hmrc.cgt.gains_by_age_band.age_0_to_15", + "status": "signed_excluded", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "signed_row": { + "dimension": "age_band", + "value": "age_0_to_15" + }, + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "name": "hmrc.cgt.gains_by_age_band.age_16_to_24", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4559831000000.0, + "resolved_value": 319000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_0e5f9867ab377dffd8a8941f" - } - ] - }, - "ons.land.corporate_land_value": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_af584dedce4184d834502e56" + }, { - "name": "ons.land.corporate_land_value", + "name": "hmrc.cgt.gains_by_age_band.age_25_to_34", "status": "active", - "matched_fact_count_overall": 30, - "matched_fact_count_at_or_before_period": 30, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2103053000000.0, + "resolved_value": 2499000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ab561a17be0af52de30cca88" - } - ] - }, - "slc.repayments.devolved_total": { - "status": "no_fact_at_or_before_period", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_40c8b42d3904c8eb44297559" + }, { - "name": "slc.repayments.devolved_total", - "status": "no_fact_at_or_before_period", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "error": "ledger_reference_compile_status_no_fact_at_or_before_period" - } - ] - }, - "slc.repayments.england_total_higher_education": { - "status": "active", - "candidates": [ + "name": "hmrc.cgt.gains_by_age_band.age_35_to_44", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 11775000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_375b4cb880dcb4caacc5f003" + }, { - "name": "slc.repayments.england_total_higher_education", + "name": "hmrc.cgt.gains_by_age_band.age_45_to_54", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 5018231834.949999, + "resolved_value": 28422000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b947d1f3c3659d252194c102" - } - ] - }, - "slc.repayments.england_plan_1": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_567f8babf11f6356f72398de" + }, { - "name": "slc.repayments.england_plan_1", + "name": "hmrc.cgt.gains_by_age_band.age_55_to_64", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1852699178.55, + "resolved_value": 38118000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d9680e6eaf243227fed5ef2" - } - ] - }, - "slc.repayments.england_plan_2": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_38da5aa08efc20c32951a860" + }, { - "name": "slc.repayments.england_plan_2", + "name": "hmrc.cgt.gains_by_age_band.age_65_to_74", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2778253361.64, + "resolved_value": 24260000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_882329821c90dc683aa778d8" - } - ] - }, - "slc.repayments.england_postgraduate": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_69e2dec98e4cdbe34c3a0572" + }, { - "name": "slc.repayments.england_postgraduate", + "name": "hmrc.cgt.gains_by_age_band.age_75_to_84", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 346409713.95000005, + "resolved_value": 11736000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ac1b07c69f1e1baa2a0fb787" - } - ] - }, - "slc.repayments.england_plan_5": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_9d0fb4e1a0c63f6d06b73e61" + }, { - "name": "slc.repayments.england_plan_5", + "name": "hmrc.cgt.gains_by_age_band.age_85_plus", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 40869580.81, + "resolved_value": 2076000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_496af6b8fe31c71c43f1d292" + "resolved_fact_key": "ledger_aggregate_fact_v2_ca2b09a93c8a40ea4766b341" } ] }, - "slc.borrowers.plan_2_above_threshold": { + "hmrc.cgt.tax_by_age_band": { "status": "active", "candidates": [ { - "name": "slc.borrowers.plan_2_above_threshold", + "name": "hmrc.cgt.tax_by_age_band.age_0_to_15", + "status": "signed_excluded", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "signed_row": { + "dimension": "age_band", + "value": "age_0_to_15" + }, + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "name": "hmrc.cgt.tax_by_age_band.age_16_to_24", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4460000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_02288c19caeae900fdaf1e0d" - } - ] - }, - "slc.borrowers.plan_2_liable": { - "status": "active", - "candidates": [ + "resolved_value": 59000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_5e45e49cdf5771a4f3dbc0c6" + }, { - "name": "slc.borrowers.plan_2_liable", + "name": "hmrc.cgt.tax_by_age_band.age_25_to_34", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 9710000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_37387933e73bcc8c1e04cf78" - } - ] - }, - "slc.borrowers.plan_5_above_threshold": { - "status": "active", - "candidates": [ + "resolved_value": 456000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_4f0a20f8646020c518ec1a6c" + }, { - "name": "slc.borrowers.plan_5_above_threshold", + "name": "hmrc.cgt.tax_by_age_band.age_35_to_44", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 35000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_dd16b085f81ef7708a00511e" - } - ] - }, - "slc.borrowers.plan_5_liable": { - "status": "active", - "candidates": [ + "resolved_value": 2246000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_041101c10e8ee3a674596ab2" + }, { - "name": "slc.borrowers.plan_5_liable", + "name": "hmrc.cgt.tax_by_age_band.age_45_to_54", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 230000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_73ff136d820950ea404ddb6b" - } - ] - }, - "slc.support.maintenance_loan_recipients": { - "status": "active", - "candidates": [ + "resolved_value": 5522000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c678a6f27d3dc149131419ee" + }, { - "name": "slc.support.maintenance_loan_recipients", + "name": "hmrc.cgt.tax_by_age_band.age_55_to_64", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1159761.0, + "resolved_value": 7152000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_f03bd7a10d0eee9917a3a199" - } - ] - }, - "slc.support.maintenance_loan_spend": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_76990ed6855fce16817d5289" + }, { - "name": "slc.support.maintenance_loan_spend", + "name": "hmrc.cgt.tax_by_age_band.age_65_to_74", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 8591659718.080004, + "resolved_value": 4409000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2900e25d7ee90f79fb3b87b9" - } - ] - }, - "slc.support.parents_learning_allowance_recipients": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_3d4b0b5873bbe5bce9c14381" + }, { - "name": "slc.support.parents_learning_allowance_recipients", + "name": "hmrc.cgt.tax_by_age_band.age_75_to_84", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 99645.0, + "resolved_value": 2260000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d5df1c69846ab2fd3d0e50e1" - } - ] - }, - "slc.support.parents_learning_allowance_spend": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_9c1150dfbd7f4f3b6235050b" + }, { - "name": "slc.support.parents_learning_allowance_spend", + "name": "hmrc.cgt.tax_by_age_band.age_85_plus", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 181421659.32, + "resolved_value": 390000000.0, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_72028ce00b9569deec79d6e6" + "resolved_fact_key": "ledger_aggregate_fact_v2_e60df0c2438533341e2f4b08" } ] }, - "slc.support.adult_dependants_grant_recipients": { + "hmrc.cgt.taxpayers_by_region": { "status": "active", "candidates": [ { - "name": "slc.support.adult_dependants_grant_recipients", + "name": "hmrc.cgt.taxpayers_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000001", + "resolved_period": 2025, + "resolved_value": 11321.91780821918, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_06f4adc777a4a3036026872f" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000002", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000002", + "resolved_period": 2025, + "resolved_value": 41513.69863013699, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_9c0d0cc201d3d0f86df9f485" + }, + { + "name": "hmrc.cgt.taxpayers_by_region@E12000003", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000003", "resolved_period": 2025, - "resolved_value": 18611.0, + "resolved_value": 32078.767123287675, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_adc83b5d137ecb48fed77064" - } - ] - }, - "slc.support.adult_dependants_grant_spend": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_abfee7a635221f3a6573857f" + }, { - "name": "slc.support.adult_dependants_grant_spend", + "name": "hmrc.cgt.taxpayers_by_region@E12000004", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 55364916.81, + "resolved_value": 31135.273972602743, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_5d42660596c9088248e41e90" - } - ] - }, - "dwp.uc.households": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_d8b059af35df8fc34df0ebfa" + }, { - "name": "dwp.uc.households", + "name": "hmrc.cgt.taxpayers_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 120, - "matched_fact_count_at_or_before_period": 120, - "matched_fact_count_in_source_window": 120, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 6197311.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_71c060f3f2a732e2f836a5d8" - } - ] - }, - "hmrc.tfc.government_top_up": { - "status": "active", - "candidates": [ + "resolved_value": 33022.260273972606, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d003284169d6847765c66221" + }, { - "name": "hmrc.tfc.government_top_up", + "name": "hmrc.cgt.taxpayers_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 9, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 599800000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_988715985f9e98bbb332e83d" - } - ] - }, - "hmrc.tfc.children_with_used_accounts": { - "status": "active", - "candidates": [ + "resolved_value": 58496.57534246576, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a48acd5e86822a82360de3c3" + }, { - "name": "hmrc.tfc.children_with_used_accounts", + "name": "hmrc.cgt.taxpayers_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 1151515.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_7aa1c663447037b35ea1c999" - } - ] - }, - "dfe.funded_childcare.working_parent_children_2_to_4": { - "status": "active", - "candidates": [ + "resolved_value": 106614.72602739726, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7bde136c5103f6b31dc478ef" + }, { - "name": "dfe.funded_childcare.working_parent_children_2_to_4", + "name": "hmrc.cgt.taxpayers_by_region@E12000008", "status": "active", - "matched_fact_count_overall": 11, - "matched_fact_count_at_or_before_period": 9, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 621482.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_a57a0c03ac43b62dde04fabd" - } - ] - }, - "dfe.funded_childcare.early_learning_2_year_olds": { - "status": "active", - "candidates": [ + "resolved_value": 114162.67123287672, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_228fb212eb226981e6213fb1" + }, { - "name": "dfe.funded_childcare.early_learning_2_year_olds", + "name": "hmrc.cgt.taxpayers_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 11, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 95031.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_a2b30af28303935159ba0edc" - } - ] - }, - "dfe.funded_childcare.universal_only_children": { - "status": "active", - "candidates": [ + "resolved_value": 60383.56164383562, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_af8dd206a47ffbc3651ece3b" + }, { - "name": "dfe.funded_childcare.universal_only_children", + "name": "hmrc.cgt.taxpayers_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 770, - "matched_fact_count_at_or_before_period": 686, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 396965.0, - "resolved_fact_period": "2025-01", - "resolved_fact_key": "ledger_aggregate_fact_v2_471573def13ebdc67ff1f40a" - } - ] - }, - "dft.bus_fare_receipts.england": { - "status": "active", - "candidates": [ + "resolved_value": 16982.87671232877, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c3fb868cb38397d0420cd136" + }, { - "name": "dft.bus_fare_receipts.england", + "name": "hmrc.cgt.taxpayers_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 3612036036.2194014, + "resolved_value": 34909.24657534247, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_2ece7c3d283b6de43b30389f", - "uprating": { - "index": "dft.local_bus_fares_index", - "factor": "1.05695792880259", - "value_before_uprating": "3417388656.43538" - } - } - ] - }, - "dft.bus_net_support.england": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e3b5a134b920d7bcf071dc5c" + }, { - "name": "dft.bus_net_support.england", + "name": "hmrc.cgt.taxpayers_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 3024904320.8399997, + "resolved_value": 9434.931506849316, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a12dfcdc0662c8a5e48bf003" + "resolved_fact_key": "ledger_aggregate_fact_v2_2779d0ba66235d3ec59280b8" } ] }, - "dft.bus_fare_receipts.london": { + "hmrc.cgt.gains_by_region": { "status": "active", "candidates": [ { - "name": "dft.bus_fare_receipts.london", + "name": "hmrc.cgt.gains_by_region@E12000001", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000001", "resolved_period": 2025, - "resolved_value": 1347434943.01459, + "resolved_value": 1497797150.3974364, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_33611c64d2048fe660501802", - "uprating": { - "index": "dft.local_bus_fares_index", - "factor": "1", - "value_before_uprating": "1347434943.01459" - } - } - ] - }, - "dft.bus_net_support.london": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_c56796163e95a924ef066aeb" + }, { - "name": "dft.bus_net_support.london", + "name": "hmrc.cgt.gains_by_region@E12000002", "status": "active", - "matched_fact_count_overall": 3, - "matched_fact_count_at_or_before_period": 3, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000002", "resolved_period": 2025, - "resolved_value": 1130214000.0, + "resolved_value": 8790074083.38308, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_d8e40cee2fc723b719ff4680" - } - ] - }, - "dft.bus_fare_receipts.england_outside_london": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_fare_receipts.england_outside_london", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." - } - ] - }, - "dft.bus_net_support.england_outside_london": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_net_support.england_outside_london", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "England outside London is England minus London: the England row and the London row (pinned at region E12000007) are both bound, so this publisher partition member is derived rather than pinned; Chronicle stamps it at statistical_scope and test_uk_bus_targets asserts the partition reconciles to England within GBP 1,000." - } - ] - }, - "dft.bus_fare_receipts.uk": { - "status": "signed_excluded", - "candidates": [ - { - "name": "dft.bus_fare_receipts.uk", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "BUS05i publishes no UK total and Microcosm declares no method to construct one." - } - ] - }, - "dft.bus_net_support.uk": { - "status": "signed_excluded", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_07d5a851c664d71dad2233c6" + }, { - "name": "dft.bus_net_support.uk", - "status": "signed_excluded", - "matched_fact_count_overall": 0, - "matched_fact_count_at_or_before_period": 0, - "signed_rationale": "BUS05i publishes no UK total and no England-to-UK uplift is declared. Net support binds instead as four country legs whose scopes differ: DfT BUS05bi net support (England, operators' view), Scottish Transport Statistics all government support (Scotland), StatsWales revenue outturn gross expenditure on concessionary fares and support to operators through local authorities only (Wales: no operator-side series and no Welsh Government grants outside the outturn), and the NITHC accounts' Public Service Obligation plus concessionary compensation as one bus-plus-rail cell excluding GBP 53.2m of other revenue funding (Northern Ireland). The legs are bound on their own terms; they are not a UK total under another name." - } - ] - }, - "obr.fuel_duties_cars": { - "status": "active", - "candidates": [ + "name": "hmrc.cgt.gains_by_region@E12000003", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000003", + "resolved_period": 2025, + "resolved_value": 6970985861.949795, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_6b4137649b34773c10d9731d" + }, { - "name": "obr.fuel_duties_cars", + "name": "hmrc.cgt.gains_by_region@E12000004", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000004", "resolved_period": 2025, - "resolved_value": 14400000000.0, + "resolved_value": 6299365751.358824, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_de6554fe8ab7b481035a432a" - } - ] - }, - "orr.rail_government_support": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_61b52be8ce7d4fc692817ba9" + }, { - "name": "orr.rail_government_support", + "name": "hmrc.cgt.gains_by_region@E12000005", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000005", "resolved_period": 2025, - "resolved_value": 21621100549.34064, + "resolved_value": 5890960774.765152, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_b16b9b3f2329455f907f9ccc" - } - ] - }, - "ons.household_energy_expenditure": { - "status": "signed_excluded", - "candidates": [ - { - "name": "ons.household_energy_expenditure", - "status": "signed_excluded", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, - "signed_rationale": "ONS Consumer Trends COICOP 04.5 (electricity, gas and other fuels) carries liquid and solid fuels the frame does not model; chronicle #271 (chronicle#270) published the 04.5.1 electricity and 04.5.2 gas sub-classes, which ons.household_electricity_expenditure and ons.household_gas_expenditure bind per fuel on the frame's own columns. The total row is retained in the contract for registry parity and signed out here (microcosm#890 F1)." - } - ] - }, - "ons.household_electricity_expenditure": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_34a10615174b9297afe221b7" + }, { - "name": "ons.household_electricity_expenditure", + "name": "hmrc.cgt.gains_by_region@E12000006", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000006", "resolved_period": 2025, - "resolved_value": 26522000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_69cd660b943ae8f21761f76a" - } - ] - }, - "ons.household_gas_expenditure": { - "status": "active", - "candidates": [ + "resolved_value": 11545870966.728456, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f15225d0bcd17c6de4da7274" + }, { - "name": "ons.household_gas_expenditure", + "name": "hmrc.cgt.gains_by_region@E12000007", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000007", "resolved_period": 2025, - "resolved_value": 15339000000.0, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_b56be49c552300f6c02fc559" - } - ] - }, - "scotgov.bus.passenger_revenue": { - "status": "active", - "candidates": [ + "resolved_value": 32519714615.602127, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_1c9e621227b5e9e0de086a29" + }, { - "name": "scotgov.bus.passenger_revenue", + "name": "hmrc.cgt.gains_by_region@E12000008", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000008", "resolved_period": 2025, - "resolved_value": 391000000.0, + "resolved_value": 25606804690.69088, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_c4269bb83534f1e46f5801c1" - } - ] - }, - "scotgov.bus.government_support": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_e292074b43a3aaf4dbd7700e" + }, { - "name": "scotgov.bus.government_support", + "name": "hmrc.cgt.gains_by_region@E12000009", "status": "active", - "matched_fact_count_overall": 2, - "matched_fact_count_at_or_before_period": 2, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "region", + "geography_id": "E12000009", "resolved_period": 2025, - "resolved_value": 499000000.0, + "resolved_value": 10341263627.509504, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_ceb60fd41d0f5587be94c234" - } - ] - }, - "welshgov.bus.public_support": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_c7cfe6f18b190daed3153cfc" + }, { - "name": "welshgov.bus.public_support", + "name": "hmrc.cgt.gains_by_region@W92000004", "status": "active", - "matched_fact_count_overall": 6, - "matched_fact_count_at_or_before_period": 6, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "W92000004", "resolved_period": 2025, - "resolved_value": 131489970.0, + "resolved_value": 2358632410.6946497, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_a10fcfec7cb458fa0c8c7f10" - } - ] - }, - "dfi_ni.bus.passenger_receipts": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_6cf6ec1d6cf7a4545c25ccb3" + }, { - "name": "dfi_ni.bus.passenger_receipts", + "name": "hmrc.cgt.gains_by_region@S92000003", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "S92000003", "resolved_period": 2025, - "resolved_value": 150082817.48999995, + "resolved_value": 5680201325.83493, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_96f72989614e0c5faaeeabbb" - } - ] - }, - "nithc.public_transport_support": { - "status": "active", - "candidates": [ + "resolved_fact_key": "ledger_aggregate_fact_v2_4af3f233994240b66f222933" + }, { - "name": "nithc.public_transport_support", + "name": "hmrc.cgt.gains_by_region@N92000002", "status": "active", - "matched_fact_count_overall": 4, - "matched_fact_count_at_or_before_period": 4, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "geography_level": "country", + "geography_id": "N92000002", "resolved_period": 2025, - "resolved_value": 111700000.0, + "resolved_value": 1757265449.747086, "resolved_fact_period": "2024", - "resolved_fact_key": "ledger_aggregate_fact_v2_be8eb7011b6f65fa65d52fcb" + "resolved_fact_key": "ledger_aggregate_fact_v2_8b23977ac0a2db5257dc6bfe" } ] }, - "dwp.uc.households_lcwra_element": { + "hmrc.cgt.taxpayers_by_gain_band": { "status": "active", "candidates": [ { - "name": "dwp.uc.households_lcwra_element", + "name": "hmrc/cgt_taxpayers_band_0", + "status": "signed_excluded", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "signed_row": { + "dimension": "cgt_gain_band", + "value": "gain_0_to_2999" + }, + "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." + }, + { + "name": "hmrc/cgt_taxpayers_band_1000000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2272425.1666666665, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f59149c4c514e1acffb728a8" - } - ] - }, - "dwp.uc.households_carer_element": { - "status": "active", - "candidates": [ + "resolved_value": 9000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_6a760ffb56140426b69a5269" + }, { - "name": "dwp.uc.households_carer_element", + "name": "hmrc/cgt_taxpayers_band_100000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1078514.5, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_d56ddfa58d7ebb3ff0178b0a" - } - ] - }, - "dwp.uc.households_housing_element": { - "status": "active", - "candidates": [ + "resolved_value": 61000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_9abad7ce7e36bcbf61e93db0" + }, { - "name": "dwp.uc.households_housing_element", + "name": "hmrc/cgt_taxpayers_band_10000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4037650.3333333335, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_04b7ec6d195e6682f0421672" - } - ] - }, - "dwp.uc.households_housing_element_social_rented": { - "status": "active", - "candidates": [ + "resolved_value": 26000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_2393740ba1c11b1a31e54e75" + }, { - "name": "dwp.uc.households_housing_element_social_rented", + "name": "hmrc/cgt_taxpayers_band_12300", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 2354587.5833333335, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_109598f6aaa42fe1387d30d1" - } - ] - }, - "dwp.uc.households_housing_element_private_rented": { - "status": "active", - "candidates": [ + "resolved_value": 97000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_c5a351873a7b2c4cc4150711" + }, { - "name": "dwp.uc.households_housing_element_private_rented", + "name": "hmrc/cgt_taxpayers_band_2000000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1570545.4166666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_7a31b88dfcd4b3d0c758a1c3" - } - ] - }, - "dwp.uc.households_childcare_element": { - "status": "active", - "candidates": [ + "resolved_value": 5000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_7a32f131c687a8bed9ec747a" + }, { - "name": "dwp.uc.households_childcare_element", + "name": "hmrc/cgt_taxpayers_band_250000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 178666.66666666666, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_0c1aa0cc56d86c50d6b2560a" - } - ] - }, - "dwp.uc.households_with_deduction": { - "status": "active", - "candidates": [ + "resolved_value": 25000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_9df6b0435f02114bbff8b83e" + }, + { + "name": "hmrc/cgt_taxpayers_band_25000", + "status": "active", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "resolved_period": 2025, + "resolved_value": 98000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_dbb814e164ce932da9f110e3" + }, { - "name": "dwp.uc.households_with_deduction", + "name": "hmrc/cgt_taxpayers_band_3000", "status": "active", - "matched_fact_count_overall": 10, - "matched_fact_count_at_or_before_period": 10, - "matched_fact_count_in_source_window": 10, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3130000.0, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f7bfdb41a462c417535602d2" - } - ] - }, - "obr.universal_credit": { - "status": "active", - "candidates": [ + "resolved_value": 73000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_445cdec889b5a04a38bfc529" + }, { - "name": "obr.universal_credit", + "name": "hmrc/cgt_taxpayers_band_5000000", "status": "active", - "matched_fact_count_overall": 14, - "matched_fact_count_at_or_before_period": 4, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 79286349139.54411, - "resolved_fact_period": "2025", - "resolved_fact_key": "ledger_aggregate_fact_v2_e680fe36115d1372d12072e1" - } - ] - }, - "dwp.hb.households": { - "status": "active", - "candidates": [ + "resolved_value": 3000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_185d64390d180e168f174c93" + }, { - "name": "dwp.hb.households", + "name": "hmrc/cgt_taxpayers_band_500000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1685702.9166666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_f2ecf4d38ef4dfc796336538" - } - ] - }, - "dwp.hb.households_social_rented": { - "status": "active", - "candidates": [ + "resolved_value": 16000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ff1311e347cb11ab13a55da8" + }, { - "name": "dwp.hb.households_social_rented", + "name": "hmrc/cgt_taxpayers_band_50000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1381089.75, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_40b45c74a40b8d085a8c28e2" - } - ] - }, - "dwp.hb.households_private_rented": { - "status": "active", - "candidates": [ + "resolved_value": 78000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_16303d73f7eadbadac68edc5" + }, { - "name": "dwp.hb.households_private_rented", + "name": "hmrc/cgt_taxpayers_band_6000", "status": "active", - "matched_fact_count_overall": 12, - "matched_fact_count_at_or_before_period": 12, - "matched_fact_count_in_source_window": 12, + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 304422.6666666667, - "resolved_fact_period": "2025-12", - "resolved_fact_key": "ledger_aggregate_fact_v2_02281858b7b0d71477e429f3" + "resolved_value": 57000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_2f1e03f344a1e1de11bf0fe3" } ] }, - "dwp.benefit_cap.capped_households_up_to_100": { + "hmrc.cgt.gains_by_gain_band": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_up_to_100", + "name": "hmrc/capital_gains_band_0", + "status": "signed_excluded", + "matched_fact_count_overall": 1, + "matched_fact_count_at_or_before_period": 1, + "signed_row": { + "dimension": "cgt_gain_band", + "value": "gain_0_to_2999" + }, + "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." + }, + { + "name": "hmrc/capital_gains_band_1000000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 38402.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_220b82ab05bec494e6dc9fe9" - } - ] - }, - "dwp.benefit_cap.capped_households_100_01_to_200": { - "status": "active", - "candidates": [ + "resolved_value": 12806000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_d4ad617897f228660a6a6be3" + }, { - "name": "dwp.benefit_cap.capped_households_100_01_to_200", + "name": "hmrc/capital_gains_band_100000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 24274.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_4a9e2cc181aee62e1eccd188" - } - ] - }, - "dwp.benefit_cap.capped_households_200_01_to_300": { - "status": "active", - "candidates": [ + "resolved_value": 9487000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_ed181e27011def0336c6cd99" + }, { - "name": "dwp.benefit_cap.capped_households_200_01_to_300", + "name": "hmrc/capital_gains_band_10000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 16240.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_5ae8289242eabcffab23f32f" - } - ] - }, - "dwp.benefit_cap.capped_households_300_01_to_400": { - "status": "active", - "candidates": [ + "resolved_value": 289000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_0ce43b4d53bb602f1b9fb49a" + }, { - "name": "dwp.benefit_cap.capped_households_300_01_to_400", + "name": "hmrc/capital_gains_band_12300", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 10562.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_a503d4e938aaf386720b96c4" - } - ] - }, - "dwp.benefit_cap.capped_households_400_01_to_500": { - "status": "active", - "candidates": [ + "resolved_value": 1747000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_52d8b43cd07113d29860cd06" + }, { - "name": "dwp.benefit_cap.capped_households_400_01_to_500", + "name": "hmrc/capital_gains_band_2000000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 7813.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_df764409769b2078c69ff113" - } - ] - }, - "dwp.benefit_cap.capped_households_500_01_to_600": { - "status": "active", - "candidates": [ + "resolved_value": 16477000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_36a58e75b04a937aa837b211" + }, { - "name": "dwp.benefit_cap.capped_households_500_01_to_600", + "name": "hmrc/capital_gains_band_250000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 4431.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_3d0e936b240ba62209777ee3" - } - ] - }, - "dwp.benefit_cap.capped_households_600_01_to_700": { - "status": "active", - "candidates": [ + "resolved_value": 8820000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e79c0dd87ea41c5469aa88af" + }, { - "name": "dwp.benefit_cap.capped_households_600_01_to_700", + "name": "hmrc/capital_gains_band_25000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 3116.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_1d68398dd88958a8700dcfac" - } - ] - }, - "dwp.benefit_cap.capped_households_700_01_to_800": { - "status": "active", - "candidates": [ + "resolved_value": 3516000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_12a05bb18f0245343b24c882" + }, { - "name": "dwp.benefit_cap.capped_households_700_01_to_800", + "name": "hmrc/capital_gains_band_3000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1902.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_999288b0fa67d7f657810a11" - } - ] - }, - "dwp.benefit_cap.capped_households_800_01_to_900": { - "status": "active", - "candidates": [ + "resolved_value": 311000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_68d13fca859e018be0915149" + }, { - "name": "dwp.benefit_cap.capped_households_800_01_to_900", + "name": "hmrc/capital_gains_band_5000000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 1328.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_b7a2d0cec131abfd0cb81ba0" - } - ] - }, - "dwp.benefit_cap.capped_households_900_01_to_1000": { - "status": "active", - "candidates": [ + "resolved_value": 48474000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_e86658beb663c322dfe3f311" + }, { - "name": "dwp.benefit_cap.capped_households_900_01_to_1000", + "name": "hmrc/capital_gains_band_500000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 824.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_80c8fa82f3e07357e677ae93" - } - ] - }, - "dwp.benefit_cap.capped_households_1000_01_to_1100": { - "status": "active", - "candidates": [ + "resolved_value": 11372000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_bcee60127caf8ba271530f73" + }, { - "name": "dwp.benefit_cap.capped_households_1000_01_to_1100", + "name": "hmrc/capital_gains_band_50000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 497.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_cf55cee33404d2283800b2b5" - } - ] - }, - "dwp.benefit_cap.capped_households_1100_01_to_1200": { - "status": "active", - "candidates": [ + "resolved_value": 5510000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_6854e6a3ad1abc041042f35d" + }, { - "name": "dwp.benefit_cap.capped_households_1100_01_to_1200", + "name": "hmrc/capital_gains_band_6000", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 380.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_6f836a33391f4352151bd27f" + "resolved_value": 448000000.0, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_f808792afed121cadff6f396" } ] }, - "dwp.benefit_cap.capped_households_1200_01_to_1300": { + "hmrc.cgt.residential_property_taxpayers": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1200_01_to_1300", + "name": "hmrc.cgt.residential_property_taxpayers.ty2024", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 239.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_ad08714cf39be9ccf0450cf2" + "resolved_value": 202630.0578034682, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_a26f1261bd153727b83045de" } ] }, - "dwp.benefit_cap.capped_households_1300_01_and_above": { + "hmrc.cgt.residential_property_gains": { "status": "active", "candidates": [ { - "name": "dwp.benefit_cap.capped_households_1300_01_and_above", + "name": "hmrc.cgt.residential_property_gains.ty2024", "status": "active", "matched_fact_count_overall": 1, "matched_fact_count_at_or_before_period": 1, "resolved_period": 2025, - "resolved_value": 627.0, - "resolved_fact_period": "2025-11", - "resolved_fact_key": "ledger_aggregate_fact_v2_a3fee6cdec1b46a15a3b1434" + "resolved_value": 12242481474.688189, + "resolved_fact_period": "2024", + "resolved_fact_key": "ledger_aggregate_fact_v2_1f8003c937764e4184da3f24" } ] } @@ -13122,6 +14512,12 @@ "active_reference_count": 100, "signed_rationale": "MHCLG council taxbase (England), Welsh Government CT1 (Wales) and Scottish Government CTAXBASE (Scotland) council-tax stock bands are declared as explicit target rows per band plus total (England and Scotland A-H, Wales A-I). The Welsh and Scottish rows resolve with their country-level geography and band pin; the English rows fan out over the nine English regions of the region tier (microcosm#905), each cell composed as the linear combination of the billing-authority facts the crosswalk places in that region (microcosm#929)." }, + { + "family": "hmrc_cgt", + "status": "active_with_row_level_signed_exclusions", + "active_reference_count": 74, + "signed_rationale": "The FY2024-25 individual CGT observations fan out three ways (microcosm#725, #467): Table 6 age bands as dimension rows (the 0-15 band and the all-ages total are signed out row by row), Table 5 country/region cells over the twelve-area region tier restated on the individuals basis by the Table 1 share through the scaled_by_ratio operation, and Table 2.1a size-of-gain bands under the incumbent banded names (the 0-2,999 band below the 2024 annual exempt amount is signed out). Chronicle's Table 2.1a package emits taxpayers and gains only, although the published sheet also carries an amounts-of-tax column, so liability binds nationally and by age band; a liability-by-size-of-gain family becomes possible once Chronicle emits that column." + }, { "family": "ons_population", "status": "active_region_tier_fanout", @@ -13141,6 +14537,41 @@ "target_id": "ons.population.scotland_households_3plus_children", "status": "signed_excluded", "signed_rationale": "Signed out pending a Scotland household-composition fact: the current selector reaches person-level ONS mid-year population age rows, not households with three or more children. microcosm#736 tracks the missing declaration." + }, + { + "family": "hmrc_cgt", + "target_id": "hmrc.cgt.gains_by_age_band", + "row": "hmrc.cgt.gains_by_age_band.age_0_to_15", + "status": "signed_excluded", + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "family": "hmrc_cgt", + "target_id": "hmrc.cgt.gains_by_gain_band", + "row": "hmrc/capital_gains_band_0", + "status": "signed_excluded", + "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." + }, + { + "family": "hmrc_cgt", + "target_id": "hmrc.cgt.tax_by_age_band", + "row": "hmrc.cgt.tax_by_age_band.age_0_to_15", + "status": "signed_excluded", + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "family": "hmrc_cgt", + "target_id": "hmrc.cgt.taxpayers_by_age_band", + "row": "hmrc.cgt.taxpayers_by_age_band.age_0_to_15", + "status": "signed_excluded", + "signed_rationale": "HMRC Table 6's 15-and-below row (1,000 taxpayers, GBP 54m of gains, GBP 9m of tax in 2024-25) has no support: the CGT incidence clone and the size-band donors place gains on the oldest adult of a household, so the frame carries no gainer under 16 and the row would always measure zero. Signed out of the age-band fan-out; the eight adult bands stay bound." + }, + { + "family": "hmrc_cgt", + "target_id": "hmrc.cgt.taxpayers_by_gain_band", + "row": "hmrc/cgt_taxpayers_band_0", + "status": "signed_excluded", + "signed_rationale": "HMRC Table 2.1a's 0-2,999 row (3,000 taxpayers with a liability on gains at or below the 2024-25 annual exempt amount of GBP 3,000, from attributed gains and prior-year adjustments) lies below the AEA gate the taxpayer proxy measures, so the model cannot place anyone in it. Signed out; the twelve bands from 3,000 stay bound." } ], "multi_fact_rationales": [] diff --git a/packages/microcosm-build/tests/test_uk_spine_acceptance_receipt.py b/packages/microcosm-build/tests/test_uk_spine_acceptance_receipt.py index 0cc86a3fb..3f0bf8cb9 100644 --- a/packages/microcosm-build/tests/test_uk_spine_acceptance_receipt.py +++ b/packages/microcosm-build/tests/test_uk_spine_acceptance_receipt.py @@ -79,6 +79,10 @@ def _apply_pending_roster_transformations( # back to the originals right after the asset-type stage. assert "cgt_incidence_anchor" not in roster roster.insert(roster.index("hmrc_cgt_asset_type_spine") + 1, "cgt_incidence_anchor") + # #930 re-mint pending: the NTS bus-travel stage imputes the journeys the + # consumption stage prices, so it runs right before lcfs_consumption. + assert "nts_bus_travel" not in roster + roster.insert(roster.index("lcfs_consumption"), "nts_bus_travel") return tuple(roster) diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index f34360418..2ca6d7089 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -811,7 +811,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" ), "policy_sha256": ( - "af670e88c0c56c18c7a5b72cfbc2a8669b214e9dfb677f00cc2464d491aa186c" + "9298a9d68b1d719700ab18a2d97b474e6354558b16a5b902d5be25ce9f9f9077" ), }, } 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 a9017600f..66e8385ae 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 @@ -13,7 +13,7 @@ "spi_sample_fraction": 0.0135, "student_loans_calibration_year": 2025 }, - "description": "Data-only inputs for reconstructing the same 30 current UK stage transform classes used by the legacy StagePlan oracle.", + "description": "Data-only inputs for reconstructing the same 31 current UK stage transform classes used by the legacy StagePlan oracle.", "inputs": { "cgt_asset_type_facts": "cgt_asset_type_facts.json", "cgt_distribution": "cgt_distribution.json", From 40a2dbe1a72e75d7833e6f9a599fab3e936fadb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Tue, 22 Sep 2026 17:55:35 +0100 Subject: [PATCH 07/19] Pin the SN 5340 NTS tabs and verify the stage's codebook against the deposited lookup tables (#930 C10) The licensed National Travel Survey extract (UKDS SN 5340, 19th edition, November 2025) is on disk: the Household, Individual and Trip tabs are pinned by size and digest and verified at runtime, and the declared codebook is checked against the deposited lookup tables and the data extract user guide. Three corrections came out of that check. The frequency-of-use question is OrdBus2Freq_B01ID (ten codes since 2019; the declared LocalBusFreq_B01ID never existed and OrdBusFreq_B01ID ended in 2018); its codes fold onto the seven NTS0313 bands, code -9 (not applicable, proxy responses) is declared a non-user because the published 2024 shares reproduce only with those persons in the base (0.526 without them, 0.505 with them, published 0.505), and -8 is dropped and receipted. Age_B01ID carries 21 bands, so the codebook maps each code to its lower age before the declared edges band donor and recipient alike; the earlier one-to-one assumption would have misaligned the QRF predictor. The trip weight is W5, which already carries the diary household weight W2, so a person's counted trips are divided by W2 before the W2-weighted mean (the user guide's 52.14 x sum(JJXSC x W5) / sum(W2)); W5xHH is only the within-household factor. Interview-only households (W2 = 0) leave the donor and are receipted. The disclosure-safe E6 bounds for the stage's band and trip columns (uk/nts_bus_travel_support_bounds.json, outward-rounded from the pinned tabs) join the terminal uk_support gate; the H2 fixture's synthetic tabs follow the verified codebook; the coverage manifest and the gate digests are regenerated. Co-Authored-By: Claude Fable 5.1 --- changelog.d/930-nts-tabs-pinned.changed.md | 1 + .../spec_engine/schema/sources.schema.json | 16 +- .../microcosm/build/uk/country_package.json | 5 + .../src/microcosm/build/uk/gates.json | 5 +- .../uk/nts_bus_travel_support_bounds.json | 34 + .../src/microcosm/build/uk/source_stages.json | 60 +- .../src/microcosm/build/uk/spec/sources.yaml | 59 +- .../build/uk_runtime/battery_bindings.py | 1 + .../build/uk_runtime/nts_bus_travel.py | 90 +- .../tests/test_country_spec.py | 3 + .../tests/test_uk_consumption_resources.py | 24 + .../tests/test_uk_frs_spine.py | 16 +- .../tests/test_uk_nts_bus_travel.py | 92 +- .../src/microcosm/data/contract.py | 2 +- .../parity/uk_spine/sources/fixture.json | 62 +- .../uk_spine/sources/nts_individual.csv | 316 ++-- .../parity/uk_spine/sources/nts_trip.csv | 1350 +++++++++-------- tools/build_uk_e6_support_bounds.py | 52 + tools/graph_uk_spine_fixture.py | 37 +- 19 files changed, 1326 insertions(+), 899 deletions(-) create mode 100644 changelog.d/930-nts-tabs-pinned.changed.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json diff --git a/changelog.d/930-nts-tabs-pinned.changed.md b/changelog.d/930-nts-tabs-pinned.changed.md new file mode 100644 index 000000000..20258030d --- /dev/null +++ b/changelog.d/930-nts-tabs-pinned.changed.md @@ -0,0 +1 @@ +The `nts_bus_travel` stage now reads the licensed National Travel Survey extract (UKDS SN 5340, 19th edition, November 2025): the Household, Individual and Trip tabs are pinned by size and digest and verified at runtime, and the declared codebook is verified against the deposited lookup tables and the data extract user guide (microcosm#930). Three corrections from that verification: the frequency-of-use question is `OrdBus2Freq_B01ID` (ten codes since 2019, folded onto the seven NTS0313 bands; code -9, not applicable, is a declared non-user because the published shares reproduce only with those persons in the base, and -8 is dropped and receipted); `Age_B01ID` carries 21 bands, so the codebook maps each code to its lower age before the declared edges band donor and recipient alike (the earlier one-to-one assumption would have misaligned the two); and the trip weight is `W5`, which already carries the diary household weight, so a person's counted trips are divided by W2 before the W2-weighted mean, exactly the user guide's 52.14 × Σ(JJXSC × W5) / Σ W2 (`trip_weight_basis: household_and_trip`, a declared and receipted basis). Interview-only households (W2 of zero) leave the donor and are receipted. The disclosure-safe E6 support bounds for the stage's band and trip columns (`uk/nts_bus_travel_support_bounds.json`, outward-rounded) join the terminal `uk_support` gate, and the H2 fixture's synthetic tabs follow the verified codebook. 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 f9fa4d23d..d7401a75a 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 @@ -8865,6 +8865,7 @@ "survey_years", "cars_clip", "age_band_edges", + "trip_weight_basis", "columns", "codes", "codebook_status" @@ -8969,7 +8970,8 @@ "income_band", "female", "main_mode", - "frequency" + "frequency", + "age_band" ], "properties": { "region": { @@ -8998,11 +9000,23 @@ "additionalProperties": { "type": "integer" } + }, + "age_band": { + "type": "object", + "additionalProperties": { + "type": "integer" + } } } }, "codebook_status": { "type": "string" + }, + "trip_weight_basis": { + "enum": [ + "trip_only", + "household_and_trip" + ] } } }, diff --git a/packages/microcosm-build/src/microcosm/build/uk/country_package.json b/packages/microcosm-build/src/microcosm/build/uk/country_package.json index da8e2e9e1..e1219c7b6 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/country_package.json +++ b/packages/microcosm-build/src/microcosm/build/uk/country_package.json @@ -262,6 +262,11 @@ "kind": "legacy_json", "schema_id": "legacy_json" }, + { + "path": "nts_bus_travel_support_bounds.json", + "kind": "legacy_json", + "schema_id": "legacy_json" + }, { "path": "local_binding_adjudications.json", "kind": "legacy_json", diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 723367e29..634437575 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -666,10 +666,11 @@ "lcfs_consumption_support_bounds.json", "etb_vat_support_bounds.json", "etb_services_support_bounds.json", - "uc_deduction_support_bounds.json" + "uc_deduction_support_bounds.json", + "nts_bus_travel_support_bounds.json" ] }, - "notes": "Every WAS/LCFS/ETB imputed output covered by support clipping must remain inside committed disclosure-safe donor support bounds. Exact donor ranges are used in-run for clipping; this release gate uses outward-rounded reviewed bounds so unit-record donor minima and maxima are never committed." + "notes": "Every WAS/LCFS/ETB imputed output covered by support clipping must remain inside committed disclosure-safe donor support bounds. Exact donor ranges are used in-run for clipping; this release gate uses outward-rounded reviewed bounds so unit-record donor minima and maxima are never committed. The nts_bus_travel person outputs (band and annual trips) are bounded by the NTS donor's ranges since microcosm#930." }, { "id": "uk_aggregate_admin", diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json new file mode 100644 index 000000000..31b7a1433 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json @@ -0,0 +1,34 @@ +{ + "version": 1, + "country": "uk", + "policy": "Disclosure-safe outward-rounded NTS bus travel support bounds generated from pinned licensed donor tabs. Values are rounded outward to one significant figure; exact donor min/max values are not committed.", + "source": { + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "household_tab_sha256": "b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7", + "individual_tab_sha256": "e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d", + "trip_tab_sha256": "878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4", + "sdc_treatment": "Exact donor min/max values are rounded outward to one significant figure before commit." + }, + "bounds": { + "bus_in_london_trips": [ + 0.0, + 2000 + ], + "local_bus_trips": [ + 0.0, + 2000 + ], + "local_bus_use_band": [ + 0.0, + 6 + ], + "other_local_bus_trips": [ + 0.0, + 2000 + ] + }, + "chronicle": [ + "Support bounds generated for NTS bus travel from source SHA pins." + ] +} 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 261edec79..baedb18dd 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1450,8 +1450,8 @@ "ukds_study_number": 5340, "doi": "10.5255/UKDA-SN-5340-19", "filename": "household_eul_2002-2024.tab", - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7", + "size_bytes": 117993975, "access": "private_local_input", "locator": "caller-supplied local input", "runtime_sha256_required": true @@ -1462,8 +1462,8 @@ "ukds_study_number": 5340, "doi": "10.5255/UKDA-SN-5340-19", "filename": "individual_eul_2002-2024.tab", - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d", + "size_bytes": 270677548, "access": "private_local_input", "locator": "caller-supplied local input", "runtime_sha256_required": true @@ -1474,8 +1474,8 @@ "ukds_study_number": 5340, "doi": "10.5255/UKDA-SN-5340-19", "filename": "trip_eul_2002-2024.tab", - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4", + "size_bytes": 1055711332, "access": "private_local_input", "locator": "caller-supplied local input", "runtime_sha256_required": true @@ -1524,6 +1524,7 @@ 60, 70 ], + "trip_weight_basis": "household_and_trip", "columns": { "household_id": "HouseholdID", "individual_id": "IndividualID", @@ -1536,9 +1537,9 @@ "household_weight": "W2", "age_band": "Age_B01ID", "sex": "Sex_B01ID", - "frequency": "LocalBusFreq_B01ID", + "frequency": "OrdBus2Freq_B01ID", "main_mode": "MainMode_B04ID", - "trip_weight": "W5xHH", + "trip_weight": "W5", "short_walk_multiplier": "JJXSC" }, "codes": { @@ -1565,15 +1566,42 @@ }, "frequency": { "1": 6, - "2": 5, - "3": 4, - "4": 3, - "5": 2, - "6": 1, - "7": 0 + "2": 6, + "3": 6, + "4": 5, + "5": 4, + "6": 3, + "7": 2, + "8": 1, + "9": 0, + "10": 0, + "-9": 0 + }, + "age_band": { + "1": 0, + "2": 1, + "3": 3, + "4": 5, + "5": 11, + "6": 16, + "7": 17, + "8": 18, + "9": 19, + "10": 20, + "11": 21, + "12": 26, + "13": 30, + "14": 40, + "15": 50, + "16": 60, + "17": 65, + "18": 70, + "19": 75, + "20": 80, + "21": 85 } }, - "codebook_status": "declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback" + "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures)." }, { "kind": "materialize_rules_engine_predictors", @@ -1764,7 +1792,7 @@ "local_bus_trips", "household_local_bus_trips" ], - "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed." + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed." }, { "stage": "lcfs_consumption", 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 6f597e910..1ef184926 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1098,8 +1098,8 @@ stages: ukds_study_number: 5340 doi: 10.5255/UKDA-SN-5340-19 filename: household_eul_2002-2024.tab - sha256: '0000000000000000000000000000000000000000000000000000000000000000' - size_bytes: 0 + sha256: b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7 + size_bytes: 117993975 access: private_local_input locator: caller-supplied local input runtime_sha256_required: true @@ -1108,8 +1108,8 @@ stages: ukds_study_number: 5340 doi: 10.5255/UKDA-SN-5340-19 filename: individual_eul_2002-2024.tab - sha256: '0000000000000000000000000000000000000000000000000000000000000000' - size_bytes: 0 + sha256: e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d + size_bytes: 270677548 access: private_local_input locator: caller-supplied local input runtime_sha256_required: true @@ -1118,8 +1118,8 @@ stages: ukds_study_number: 5340 doi: 10.5255/UKDA-SN-5340-19 filename: trip_eul_2002-2024.tab - sha256: '0000000000000000000000000000000000000000000000000000000000000000' - size_bytes: 0 + sha256: 878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4 + size_bytes: 1055711332 access: private_local_input locator: caller-supplied local input runtime_sha256_required: true @@ -1156,6 +1156,7 @@ stages: - 50 - 60 - 70 + trip_weight_basis: household_and_trip columns: household_id: HouseholdID individual_id: IndividualID @@ -1168,9 +1169,9 @@ stages: household_weight: W2 age_band: Age_B01ID sex: Sex_B01ID - frequency: LocalBusFreq_B01ID + frequency: OrdBus2Freq_B01ID main_mode: MainMode_B04ID - trip_weight: W5xHH + trip_weight: W5 short_walk_multiplier: JJXSC codes: region: @@ -1193,13 +1194,39 @@ stages: other_local_bus: 8 frequency: '1': 6 - '2': 5 - '3': 4 - '4': 3 - '5': 2 - '6': 1 - '7': 0 - codebook_status: declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback + '2': 6 + '3': 6 + '4': 5 + '5': 4 + '6': 3 + '7': 2 + '8': 1 + '9': 0 + '10': 0 + '-9': 0 + age_band: + '1': 0 + '2': 1 + '3': 3 + '4': 5 + '5': 11 + '6': 16 + '7': 17 + '8': 18 + '9': 19 + '10': 20 + '11': 21 + '12': 26 + '13': 30 + '14': 40 + '15': 50 + '16': 60 + '17': 65 + '18': 70 + '19': 75 + '20': 80 + '21': 85 + codebook_status: verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures). - kind: materialize_rules_engine_predictors predictors: - household_gross_income @@ -1335,7 +1362,7 @@ stages: - other_local_bus_trips - local_bus_trips - household_local_bus_trips - notes: Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed. + notes: Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed. - stage: lcfs_consumption survey: Living Costs and Food Survey 2023-24 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. 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 28a096c3b..23039c8dd 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 @@ -547,6 +547,7 @@ def _evaluate_support( "etb_vat_support_bounds.json", "etb_services_support_bounds.json", "uc_deduction_support_bounds.json", + "nts_bus_travel_support_bounds.json", } if set(resource_names) - allowed: raise ValueError( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py index a907dfb10..f8593975d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py @@ -133,6 +133,16 @@ NON_USER_BAND = 0 MAX_BAND = len(BAND_IDS) - 1 BAND_SALT_QUANTILE = "nts_bus_use_band_quantile" +#: How the declared trip weight relates to the household weight: ``trip_only`` +#: is a within-household factor (multiply by it), ``household_and_trip`` is the +#: NTS W5 trip weight that already carries the diary household weight W2, so a +#: person's counted trips are divided by W2 before the W2-weighted mean (the +#: user guide's 52.14 x sum(JJXSC x W5) / sum(W2)). +TRIP_WEIGHT_TRIP_ONLY = "trip_only" +TRIP_WEIGHT_HOUSEHOLD_AND_TRIP = "household_and_trip" +TRIP_WEIGHT_BASES: frozenset[str] = frozenset( + {TRIP_WEIGHT_TRIP_ONLY, TRIP_WEIGHT_HOUSEHOLD_AND_TRIP} +) BAND_SALT_SIGN = "nts_bus_use_band_sign" WEEKS_IN_YEAR = 52.14 LONDON_GROUP = "london" @@ -195,6 +205,8 @@ class NTSColumns: london_region_code: int income_band_codes: Mapping[int, int] age_band_edges: tuple[int, ...] + age_band_codes: Mapping[int, int] + trip_weight_basis: str female_code: int mode_codes: Mapping[str, int] frequency_codes: Mapping[int, int] @@ -250,6 +262,23 @@ def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: raise NTSBusTravelError( "age_band_edges must be an ascending list of lower bounds starting at 0." ) + age_band_codes = { + int(code): int(lower) + for code, lower in _mapping(codes.get("age_band"), "codes.age_band").items() + } + if not age_band_codes or min(age_band_codes.values()) != 0: + raise NTSBusTravelError( + "codes.age_band must map every NTS age-band code to the band's " + "lower age in years, the youngest band to 0." + ) + trip_weight_basis = str( + parameters.get("trip_weight_basis", TRIP_WEIGHT_TRIP_ONLY) + ) + if trip_weight_basis not in TRIP_WEIGHT_BASES: + raise NTSBusTravelError( + f"trip_weight_basis must be one of {sorted(TRIP_WEIGHT_BASES)}, " + f"got {trip_weight_basis!r}." + ) mode_codes = { str(series): int(code) for series, code in _mapping( @@ -295,6 +324,8 @@ def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: london_region_code=int(london[0]), income_band_codes=income_codes, age_band_edges=edges, + age_band_codes=age_band_codes, + trip_weight_basis=trip_weight_basis, female_code=int(codes.get("female", 2)), mode_codes=mode_codes, frequency_codes=frequency_codes, @@ -405,6 +436,7 @@ def clean_nts_travel_tables( f"NTS household table has no rows for survey years {columns.survey_years}." ) weight = pd.to_numeric(hh[columns.household_weight], errors="coerce") + households_zero_weight = int((~(weight.notna() & (weight > 0))).sum()) hh = hh.loc[weight.notna() & (weight > 0)].copy() region_code = pd.to_numeric(hh[columns.region], errors="coerce") region = region_code.map(columns.region_codes) @@ -451,21 +483,26 @@ def clean_nts_travel_tables( ] person = person.merge(hh_keep, on=columns.household_id, how="inner") age_code = pd.to_numeric(person[columns.age_band], errors="coerce") - # The NTS band code is 1-based and ordered like the declared edges. - person["age_band"] = (age_code - 1).clip( - lower=0, upper=len(columns.age_band_edges) - 1 + # The NTS band code maps to the band's lower age through the declared + # codebook; the declared edges then band donor and recipient alike. + age_lower = age_code.map(columns.age_band_codes) + persons_unmapped_age = int(age_lower.isna().sum()) + person = person.loc[age_lower.notna()].copy() + person["age_lower"] = age_lower.loc[person.index].astype(float) + person["age_band"] = age_band_ordinal( + person["age_lower"].to_numpy(), columns.age_band_edges ) - person = person.loc[age_code.notna()].copy() - person["age_band"] = person["age_band"].astype(np.int64) sex = pd.to_numeric(person[columns.sex], errors="coerce") person["is_female"] = (sex == columns.female_code).astype(np.int64) frequency_source = FREQUENCY_SOURCE_PUBLISHED_SHARES + persons_unmapped_frequency = 0 if columns.frequency is not None and columns.frequency in ind.columns: freq = pd.to_numeric( ind.set_index(columns.individual_id)[columns.frequency], errors="coerce" ) band = person[columns.individual_id].map(freq).map(columns.frequency_codes) known = band.notna() + persons_unmapped_frequency = int((~known).sum()) person = person.loc[known].copy() person[BAND_COLUMN] = band.loc[person.index].astype(np.int64) frequency_source = FREQUENCY_SOURCE_INTERVIEW @@ -477,6 +514,13 @@ def clean_nts_travel_tables( tr[columns.short_walk_multiplier], errors="coerce" ).fillna(0.0) counted = trip_weight * multiplier + if columns.trip_weight_basis == TRIP_WEIGHT_HOUSEHOLD_AND_TRIP: + # W5 carries W2: divide it out so the W2-weighted person mean below + # reproduces the publisher's sum(JJXSC x W5) / sum(W2). + household_weight = tr[columns.individual_id].map( + person.set_index(columns.individual_id)["weight"] + ) + counted = counted / household_weight.to_numpy(dtype=float) for series in SERIES: code = columns.mode_codes[series] per_person = ( @@ -506,6 +550,7 @@ def clean_nts_travel_tables( "region", "residence_group", "age_band", + "age_lower", "is_female", "num_vehicles", "household_size", @@ -527,8 +572,13 @@ def clean_nts_travel_tables( "weighted_persons": float(person["weight"].sum()), "households_unmapped_region": unmapped, "households_missing_income_band": income_missing, + "households_zero_weight": households_zero_weight, + "persons_unmapped_age": persons_unmapped_age, + "persons_unmapped_frequency": persons_unmapped_frequency, "frequency_source": frequency_source, "frequency_column": columns.frequency, + "trip_weight_column": columns.trip_weight, + "trip_weight_basis": columns.trip_weight_basis, "annualisation_weeks": WEEKS_IN_YEAR, "trips_per_person": { series: float(np.average(person[column], weights=person["weight"])) @@ -538,6 +588,24 @@ def clean_nts_travel_tables( return NTSDonor(person=person, frequency_source=frequency_source, receipt=receipt) +def nts_support_ranges(donor: pd.DataFrame) -> dict[str, tuple[float, float]]: + """Per-column donor min/max of the support-clip columns (the E6 bounds input). + + The band range is the declared ordinal range; the trips are the cleaned + donor persons' annual diary trips per series and in total. + """ + + ranges: dict[str, tuple[float, float]] = { + BAND_COLUMN: (float(NON_USER_BAND), float(MAX_BAND)) + } + for column in UK_NTS_SUPPORT_CLIP_COLUMNS: + if column == BAND_COLUMN: + continue + values = donor[column].to_numpy(dtype=float) + ranges[column] = (float(values.min()), float(values.max())) + return ranges + + # -------------------------------------------------------------------------- # Recipient predictors # -------------------------------------------------------------------------- @@ -1235,9 +1303,7 @@ def __call__(self, frame: Frame) -> Frame: # Donor-side eligible share of trips per series (the fare-paying share # the pricing step reads beside the publisher's concessionary share). donor_regions = donor.person["region"].to_numpy().astype(str) - donor_ages = _band_lower_ages( - donor.person["age_band"].to_numpy(), columns.age_band_edges - ) + donor_ages = donor.person["age_lower"].to_numpy(dtype=float) donor_eligible, _ = assign_bus_pass_eligibility( donor_ages, donor_regions, rules ) @@ -1250,7 +1316,8 @@ def __call__(self, frame: Frame) -> Frame: ) eligibility_receipt["donor_eligible_trip_share"] = eligible_trip_share eligibility_receipt["donor_age_basis"] = ( - "band lower bound (the extract carries banded ages)" + "NTS age-band lower bound (the extract carries banded ages; the " + "declared codebook maps each band code to its lower age)" ) # Person-level support clip on the band and the trips. draws = pd.DataFrame({BAND_COLUMN: band.astype(float), **trips}) @@ -1384,11 +1451,6 @@ def checkpoint_metadata(self) -> dict[str, object]: return {"evidence": self.last_result.evidence()} -def _band_lower_ages(age_band: np.ndarray, edges: Sequence[int]) -> np.ndarray: - lower = np.asarray(edges, dtype=float) - return lower[np.clip(np.asarray(age_band, dtype=int), 0, len(lower) - 1)] - - def _trip_rate_receipt( person: pd.DataFrame, recipient: pd.DataFrame, diff --git a/packages/microcosm-build/tests/test_country_spec.py b/packages/microcosm-build/tests/test_country_spec.py index 487e10c4e..33bddc512 100644 --- a/packages/microcosm-build/tests/test_country_spec.py +++ b/packages/microcosm-build/tests/test_country_spec.py @@ -962,6 +962,7 @@ def test_spi_spine_adds_no_country_package_resources(self) -> None: "local_registry_parity_fixture_2025.json", "was_wealth_support_bounds.json", "uc_deduction_support_bounds.json", + "nts_bus_travel_support_bounds.json", "local_binding_adjudications.json", "local_area_support_exclusions.json", "uk_local_target_census.json", @@ -1074,6 +1075,7 @@ def test_uk_package_loads(self) -> None: "local_registry_parity_fixture_2025.json", "was_wealth_support_bounds.json", "uc_deduction_support_bounds.json", + "nts_bus_travel_support_bounds.json", "local_binding_adjudications.json", "local_area_support_exclusions.json", "uk_local_target_census.json", @@ -1508,6 +1510,7 @@ def test_thresholds_match_the_schema4_manifest(self, manifest) -> None: "etb_vat_support_bounds.json", "etb_services_support_bounds.json", "uc_deduction_support_bounds.json", + "nts_bus_travel_support_bounds.json", ) aggregate = params["uk_aggregate_admin"] assert aggregate["default_rtol"] == 0.15 diff --git a/packages/microcosm-build/tests/test_uk_consumption_resources.py b/packages/microcosm-build/tests/test_uk_consumption_resources.py index 46dbfb7e4..386780df2 100644 --- a/packages/microcosm-build/tests/test_uk_consumption_resources.py +++ b/packages/microcosm-build/tests/test_uk_consumption_resources.py @@ -135,10 +135,34 @@ def test_e6_support_bounds_resources_are_sha_bound_and_non_placeholder() -> None "dfe_education_spending", "rail_subsidy_spending", } + # The NTS bus-travel bounds (microcosm#930) bind the SN 5340 19th-edition + # tabs and cover the stage's four person-level clip columns. + nts = _load("nts_bus_travel_support_bounds.json") + assert nts["source"]["ukds_study_number"] == 5340 + assert nts["source"]["household_tab_sha256"] == ( + "b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7" + ) + assert nts["source"]["individual_tab_sha256"] == ( + "e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d" + ) + assert nts["source"]["trip_tab_sha256"] == ( + "878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4" + ) + assert set(nts["bounds"]) == { + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + } + assert nts["bounds"]["local_bus_use_band"] == [0.0, 6.0] + for column in ("bus_in_london_trips", "other_local_bus_trips", "local_bus_trips"): + low, high = nts["bounds"][column] + assert low == 0.0 and high > 0.0 for name in ( "lcfs_consumption_support_bounds.json", "etb_vat_support_bounds.json", "etb_services_support_bounds.json", + "nts_bus_travel_support_bounds.json", ): assert ( "placeholder" not in (UK_PACKAGE / name).read_text(encoding="utf-8").lower() diff --git a/packages/microcosm-build/tests/test_uk_frs_spine.py b/packages/microcosm-build/tests/test_uk_frs_spine.py index 267f19373..8c4b0cf8b 100644 --- a/packages/microcosm-build/tests/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/test_uk_frs_spine.py @@ -2070,18 +2070,14 @@ def test_input_artifact_pins_bind_spi_donor_and_ods() -> None: "qrf_donor", "was_qrf_donor", } - # The NTS tabs (#930) are declared with placeholder pins until the licensed - # extract lands: a zero size and an all-zero digest the runtime refuses. - # Flip this to the positive branch when the tabs are pinned. - pending = {"nts_household_tab", "nts_individual_tab", "nts_trip_tab"} - for role, pin in pins.items(): + # Every private input, the three NTS tabs included since the SN 5340 + # 19th-edition extract was pinned (#930), carries a real size and digest. + for pin in pins.values(): assert len(str(pin["sha256"])) == 64 + assert str(pin["sha256"]) != "0" * 64 assert str(pin["filename"]) - if role in pending: - assert int(pin["size_bytes"]) == 0 - assert str(pin["sha256"]) == "0" * 64 - else: - assert int(pin["size_bytes"]) > 0 + assert int(pin["size_bytes"]) > 0 + assert pins["nts_trip_tab"]["filename"] == "trip_eul_2002-2024.tab" declared = { str(artifact["role"]): str(artifact["sha256"]) for stage_name in ( diff --git a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py index 31bf74c5d..9f0b16b80 100644 --- a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py +++ b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py @@ -79,19 +79,22 @@ def _synthetic_nts( row = { "IndividualID": index, "HouseholdID": int(household_id), - "Age_B01ID": 1 + index % 10, + "Age_B01ID": 1 + index % 21, "Sex_B01ID": 1 + index % 2, } if frequency: - row["LocalBusFreq_B01ID"] = 1 + index % 7 + # The ten OrdBus2Freq_B01ID codes, every one populated. + row["OrdBus2Freq_B01ID"] = 1 + (int(household_id) + member) % 10 persons.append(row) individual = pd.DataFrame(persons) + w2 = dict(zip(household["HouseholdID"], household["W2"], strict=True)) trips = [] trip_id = 1 for _, person in individual.iterrows(): - band_code = int(person.get("LocalBusFreq_B01ID", 7)) - count = max(0, 7 - band_code) + code = int(person.get("OrdBus2Freq_B01ID", 10)) + count = max(0, 9 - code) london = (int(person["HouseholdID"]) - 1000) % 9 == 6 + household_weight = float(w2[int(person["HouseholdID"])]) for t in range(count): trips.append( { @@ -99,7 +102,8 @@ def _synthetic_nts( "IndividualID": int(person["IndividualID"]), "HouseholdID": int(person["HouseholdID"]), "MainMode_B04ID": 7 if london else 8, - "W5xHH": 1.0 + (t % 3) / 10.0, + # W5 carries W2 (the household_and_trip basis). + "W5": household_weight * (1.0 + (t % 3) / 10.0), "JJXSC": 1.0, } ) @@ -110,7 +114,7 @@ def _synthetic_nts( "IndividualID": int(person["IndividualID"]), "HouseholdID": int(person["HouseholdID"]), "MainMode_B04ID": 3, - "W5xHH": 1.0, + "W5": household_weight, "JJXSC": 1.0, } ) @@ -133,7 +137,14 @@ def test_declared_columns_and_codes_parse_from_the_committed_stage() -> None: "SOUTH_WEST", } assert columns.mode_codes == {BUS_IN_LONDON: 7, OTHER_LOCAL_BUS: 8} - assert columns.frequency_codes[1] == MAX_BAND and columns.frequency_codes[7] == 0 + # OrdBus2Freq_B01ID: codes 1-3 are the top band, 9 and 10 the non-user + # band, and -9 (not applicable) is declared a non-user. + assert columns.frequency_codes[1] == MAX_BAND + assert columns.frequency_codes[3] == MAX_BAND + assert columns.frequency_codes[10] == 0 and columns.frequency_codes[-9] == 0 + assert -8 not in columns.frequency_codes + assert columns.trip_weight_basis == "household_and_trip" + assert columns.age_band_codes[1] == 0 and columns.age_band_codes[21] == 85 assert columns.survey_years == (2022, 2023, 2024) bad = dict(_operation(_committed_stage(), "clean_nts_travel_tables")) bad["codes"] = {**bad["codes"], "main_mode": {"bus_in_london": 7}} @@ -150,15 +161,29 @@ def test_cleaning_annualises_diary_trips_per_series_and_maps_the_codebook() -> N assert set(person["region"]) <= set(_columns().region_codes.values()) assert set(person["income_band"]) == {1, 2, 3} assert person["num_vehicles"].between(0, 5).all() - # Frequency code 1 (3+ a week) is the top band; code 7 the non-user band. - codes = individual.set_index("IndividualID")["LocalBusFreq_B01ID"] - expected = person["individual_id"].map(codes).map(lambda c: 7 - int(c)) + # The interview code maps onto the band through the declared codebook. + codes = individual.set_index("IndividualID")["OrdBus2Freq_B01ID"] + expected = person["individual_id"].map(codes).map(_columns().frequency_codes) assert (person["local_bus_use_band"].to_numpy() == expected.to_numpy()).all() - # Trips: 52.14 x sum(W5xHH x JJXSC) over the bus trips only. + # Age: the NTS band code's lower age, banded on the declared edges (code 4 + # is 5-10, the second declared band; code 17 is 65-69, the ninth). + age_codes = individual.set_index("IndividualID")["Age_B01ID"] + lower = person["individual_id"].map(age_codes).map(_columns().age_band_codes) + assert (person["age_lower"].to_numpy() == lower.to_numpy()).all() + assert ( + person.loc[lower == 5, "age_band"].eq(1).all() + and person.loc[lower == 65, "age_band"].eq(8).all() + ) + # Trips: 52.14 x sum(W5 x JJXSC) / W2 over the bus trips only (W5 carries W2). bus = trip[trip["MainMode_B04ID"].isin([7, 8])] - per_person = (bus["W5xHH"] * bus["JJXSC"]).groupby(bus["IndividualID"]).sum() + w2 = household.set_index("HouseholdID")["W2"] + counted = bus["W5"] * bus["JJXSC"] / bus["HouseholdID"].map(w2) + per_person = counted.groupby(bus["IndividualID"]).sum() expected_trips = person["individual_id"].map(per_person).fillna(0.0) * WEEKS_IN_YEAR assert np.allclose(person["local_bus_trips"], expected_trips) + assert donor.receipt["trip_weight_basis"] == "household_and_trip" + assert donor.receipt["households_zero_weight"] == 0 + assert donor.receipt["persons_unmapped_frequency"] == 0 london = person["residence_group"] == LONDON_GROUP assert (person.loc[london, "other_local_bus_trips"] == 0).all() assert (person.loc[~london, "bus_in_london_trips"] == 0).all() @@ -171,12 +196,53 @@ def test_cleaning_annualises_diary_trips_per_series_and_maps_the_codebook() -> N ) +def test_cleaning_handles_the_nts_sentinels_and_the_diary_sample() -> None: + """-9 is a declared non-user, -8 and unknown age codes drop, W2 = 0 leaves.""" + + household, individual, trip = _synthetic_nts() + individual = individual.copy() + first, second, third = individual.index[:3] + individual.loc[first, "OrdBus2Freq_B01ID"] = -9 + individual.loc[second, "OrdBus2Freq_B01ID"] = -8 + individual.loc[third, "Age_B01ID"] = -8 + household = household.copy() + # An interview-only household: W2 of zero, so it leaves the donor. + zero = household.index[-1] + household.loc[zero, "W2"] = 0.0 + zero_id = int(household.loc[zero, "HouseholdID"]) + donor = clean_nts_travel_tables(household, individual, trip, columns=_columns()) + person = donor.person + ids = set(person["individual_id"]) + assert int(individual.loc[first, "IndividualID"]) in ids + assert ( + person.loc[ + person["individual_id"] == int(individual.loc[first, "IndividualID"]), + "local_bus_use_band", + ].item() + == 0 + ) + assert int(individual.loc[second, "IndividualID"]) not in ids + assert int(individual.loc[third, "IndividualID"]) not in ids + assert zero_id not in set(person["household_id"]) + assert donor.receipt["persons_unmapped_frequency"] == 1 + assert donor.receipt["persons_unmapped_age"] == 1 + assert donor.receipt["households_zero_weight"] == 1 + bad = dict(_operation(_committed_stage(), "clean_nts_travel_tables")) + bad["trip_weight_basis"] = "per_stage" + with pytest.raises(NTSBusTravelError, match="trip_weight_basis"): + NTSColumns.from_parameters(bad) + bad = dict(_operation(_committed_stage(), "clean_nts_travel_tables")) + bad["codes"] = {**bad["codes"], "age_band": {"1": 5}} + with pytest.raises(NTSBusTravelError, match="codes.age_band"): + NTSColumns.from_parameters(bad) + + def test_cleaning_falls_back_to_published_shares_without_a_frequency_column() -> None: household, individual, trip = _synthetic_nts(frequency=False) donor = clean_nts_travel_tables(household, individual, trip, columns=_columns()) assert donor.frequency_source == "published_shares" assert "local_bus_use_band" not in donor.person - assert donor.receipt["frequency_column"] == "localbusfreq_b01id" + assert donor.receipt["frequency_column"] == "ordbus2freq_b01id" def _recipient_frame(n: int = 240, *, seed: int = 3): diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 2ca6d7089..eb7b2c98b 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -811,7 +811,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" ), "policy_sha256": ( - "9298a9d68b1d719700ab18a2d97b474e6354558b16a5b902d5be25ce9f9f9077" + "11fe34504eecefa7ca584ccecd3c8c6131db71aa2f96f0d6337b2c9fbd55a738" ), }, } 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 66e8385ae..6c4148fa5 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 @@ -3671,8 +3671,8 @@ "locator": "caller-supplied local input", "role": "nts_household_tab", "runtime_sha256_required": true, - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7", + "size_bytes": 117993975, "ukds_study_number": 5340 }, { @@ -3683,8 +3683,8 @@ "locator": "caller-supplied local input", "role": "nts_individual_tab", "runtime_sha256_required": true, - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d", + "size_bytes": 270677548, "ukds_study_number": 5340 }, { @@ -3695,8 +3695,8 @@ "locator": "caller-supplied local input", "role": "nts_trip_tab", "runtime_sha256_required": true, - "sha256": "0000000000000000000000000000000000000000000000000000000000000000", - "size_bytes": 0, + "sha256": "878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4", + "size_bytes": 1055711332, "ukds_study_number": 5340 }, { @@ -3726,7 +3726,7 @@ "local_bus_trips", "household_local_bus_trips" ], - "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are placeholders refused at runtime until the licensed tabs land and are pinned, and the H2 fixture drives the stage with synthetic tabs. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed.", + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed.", "operations": [ { "age_band_edges": [ @@ -3745,17 +3745,44 @@ 0, 5 ], - "codebook_status": "declared from the NTS user guide (weights W2, W5xHH, JJXSC; 52.14 weeks; England only from 2013) and the published tables; the column names and codes are verified against the deposited lookup tables when the extract lands, and a missing frequency column selects the published-shares fallback", + "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures).", "codes": { + "age_band": { + "1": 0, + "10": 20, + "11": 21, + "12": 26, + "13": 30, + "14": 40, + "15": 50, + "16": 60, + "17": 65, + "18": 70, + "19": 75, + "2": 1, + "20": 80, + "21": 85, + "3": 3, + "4": 5, + "5": 11, + "6": 16, + "7": 17, + "8": 18, + "9": 19 + }, "female": 2, "frequency": { + "-9": 0, "1": 6, - "2": 5, - "3": 4, - "4": 3, - "5": 2, - "6": 1, - "7": 0 + "10": 0, + "2": 6, + "3": 6, + "4": 5, + "5": 4, + "6": 3, + "7": 2, + "8": 1, + "9": 0 }, "income_band": { "1": 1, @@ -3781,7 +3808,7 @@ "columns": { "age_band": "Age_B01ID", "cars": "NumCarVan", - "frequency": "LocalBusFreq_B01ID", + "frequency": "OrdBus2Freq_B01ID", "household_id": "HouseholdID", "household_size": "HHoldNumPeople", "household_weight": "W2", @@ -3793,7 +3820,7 @@ "short_walk_multiplier": "JJXSC", "survey_year": "SurveyYear", "trip_id": "TripID", - "trip_weight": "W5xHH" + "trip_weight": "W5" }, "kind": "clean_nts_travel_tables", "lowercase_columns": true, @@ -3801,7 +3828,8 @@ 2022, 2023, 2024 - ] + ], + "trip_weight_basis": "household_and_trip" }, { "consumed_only": true, diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv index 8cf9276bd..3e05e13c8 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_individual.csv @@ -1,161 +1,161 @@ -IndividualID,HouseholdID,Age_B01ID,Sex_B01ID,LocalBusFreq_B01ID -10000,1000,1,1,5 -10010,1001,1,1,1 -10011,1001,2,2,2 -10020,1002,1,1,4 -10021,1002,2,2,5 -10022,1002,3,1,6 -10030,1003,1,1,7 -10031,1003,2,2,1 -10032,1003,3,1,2 -10033,1003,4,2,3 -10040,1004,1,1,3 -10050,1005,1,1,6 -10051,1005,2,2,7 -10060,1006,1,1,2 -10061,1006,2,2,3 -10062,1006,3,1,4 -10070,1007,1,1,5 -10071,1007,2,2,6 -10072,1007,3,1,7 -10073,1007,4,2,1 -10080,1008,1,1,1 -10090,1009,1,1,4 -10091,1009,2,2,5 -10100,1010,1,1,7 -10101,1010,2,2,1 -10102,1010,3,1,2 -10110,1011,1,1,3 -10111,1011,2,2,4 -10112,1011,3,1,5 -10113,1011,4,2,6 -10120,1012,1,1,6 -10130,1013,1,1,2 -10131,1013,2,2,3 -10140,1014,1,1,5 -10141,1014,2,2,6 -10142,1014,3,1,7 -10150,1015,1,1,1 -10151,1015,2,2,2 -10152,1015,3,1,3 -10153,1015,4,2,4 -10160,1016,1,1,4 -10170,1017,1,1,7 -10171,1017,2,2,1 -10180,1018,1,1,3 -10181,1018,2,2,4 -10182,1018,3,1,5 -10190,1019,1,1,6 -10191,1019,2,2,7 -10192,1019,3,1,1 -10193,1019,4,2,2 -10200,1020,1,1,2 -10210,1021,1,1,5 -10211,1021,2,2,6 -10220,1022,1,1,1 -10221,1022,2,2,2 -10222,1022,3,1,3 -10230,1023,1,1,4 -10231,1023,2,2,5 -10232,1023,3,1,6 -10233,1023,4,2,7 -10240,1024,1,1,7 -10250,1025,1,1,3 -10251,1025,2,2,4 -10260,1026,1,1,6 -10261,1026,2,2,7 -10262,1026,3,1,1 -10270,1027,1,1,2 -10271,1027,2,2,3 -10272,1027,3,1,4 -10273,1027,4,2,5 -10280,1028,1,1,5 -10290,1029,1,1,1 -10291,1029,2,2,2 -10300,1030,1,1,4 -10301,1030,2,2,5 -10302,1030,3,1,6 -10310,1031,1,1,7 -10311,1031,2,2,1 -10312,1031,3,1,2 -10313,1031,4,2,3 -10320,1032,1,1,3 -10330,1033,1,1,6 -10331,1033,2,2,7 -10340,1034,1,1,2 -10341,1034,2,2,3 -10342,1034,3,1,4 -10350,1035,1,1,5 -10351,1035,2,2,6 -10352,1035,3,1,7 -10353,1035,4,2,1 -10360,1036,1,1,1 -10370,1037,1,1,4 -10371,1037,2,2,5 -10380,1038,1,1,7 -10381,1038,2,2,1 -10382,1038,3,1,2 -10390,1039,1,1,3 -10391,1039,2,2,4 -10392,1039,3,1,5 -10393,1039,4,2,6 -10400,1040,1,1,6 -10410,1041,1,1,2 -10411,1041,2,2,3 -10420,1042,1,1,5 -10421,1042,2,2,6 -10422,1042,3,1,7 -10430,1043,1,1,1 -10431,1043,2,2,2 -10432,1043,3,1,3 -10433,1043,4,2,4 -10440,1044,1,1,4 -10450,1045,1,1,7 -10451,1045,2,2,1 -10460,1046,1,1,3 -10461,1046,2,2,4 -10462,1046,3,1,5 -10470,1047,1,1,6 -10471,1047,2,2,7 -10472,1047,3,1,1 -10473,1047,4,2,2 -10480,1048,1,1,2 -10490,1049,1,1,5 -10491,1049,2,2,6 +IndividualID,HouseholdID,Age_B01ID,Sex_B01ID,OrdBus2Freq_B01ID +10000,1000,5,1,1 +10010,1001,15,1,2 +10011,1001,16,2,3 +10020,1002,4,1,-9 +10021,1002,5,2,4 +10022,1002,6,1,5 +10030,1003,14,1,4 +10031,1003,15,2,-9 +10032,1003,16,1,6 +10033,1003,17,2,7 +10040,1004,3,1,5 +10050,1005,13,1,6 +10051,1005,14,2,7 +10060,1006,2,1,7 +10061,1006,3,2,8 +10062,1006,4,1,9 +10070,1007,12,1,8 +10071,1007,13,2,9 +10072,1007,14,1,10 +10073,1007,15,2,1 +10080,1008,1,1,9 +10090,1009,11,1,10 +10091,1009,12,2,1 +10100,1010,21,1,1 +10101,1010,1,2,2 +10102,1010,2,1,3 +10110,1011,10,1,2 +10111,1011,11,2,3 +10112,1011,12,1,4 +10113,1011,13,2,5 +10120,1012,20,1,3 +10130,1013,9,1,-9 +10131,1013,10,2,5 +10140,1014,19,1,5 +10141,1014,20,2,-9 +10142,1014,21,1,7 +10150,1015,8,1,6 +10151,1015,9,2,7 +10152,1015,10,1,-9 +10153,1015,11,2,9 +10160,1016,18,1,7 +10170,1017,7,1,8 +10171,1017,8,2,9 +10180,1018,17,1,9 +10181,1018,18,2,10 +10182,1018,19,1,1 +10190,1019,6,1,10 +10191,1019,7,2,1 +10192,1019,8,1,2 +10193,1019,9,2,3 +10200,1020,16,1,1 +10210,1021,5,1,2 +10211,1021,6,2,3 +10220,1022,15,1,3 +10221,1022,16,2,4 +10222,1022,17,1,5 +10230,1023,4,1,4 +10231,1023,5,2,5 +10232,1023,6,1,6 +10233,1023,7,2,7 +10240,1024,14,1,-9 +10250,1025,3,1,6 +10251,1025,4,2,-9 +10260,1026,13,1,7 +10261,1026,14,2,8 +10262,1026,15,1,-9 +10270,1027,2,1,8 +10271,1027,3,2,9 +10272,1027,4,1,10 +10273,1027,5,2,-9 +10280,1028,12,1,9 +10290,1029,1,1,10 +10291,1029,2,2,1 +10300,1030,11,1,1 +10301,1030,12,2,2 +10302,1030,13,1,3 +10310,1031,21,1,2 +10311,1031,1,2,3 +10312,1031,2,1,4 +10313,1031,3,2,5 +10320,1032,10,1,3 +10330,1033,20,1,4 +10331,1033,21,2,5 +10340,1034,9,1,5 +10341,1034,10,2,6 +10342,1034,11,1,7 +10350,1035,19,1,-9 +10351,1035,20,2,7 +10352,1035,21,1,8 +10353,1035,1,2,9 +10360,1036,8,1,7 +10370,1037,18,1,8 +10371,1037,19,2,9 +10380,1038,7,1,9 +10381,1038,8,2,10 +10382,1038,9,1,1 +10390,1039,17,1,10 +10391,1039,18,2,1 +10392,1039,19,1,2 +10393,1039,20,2,3 +10400,1040,6,1,1 +10410,1041,16,1,2 +10411,1041,17,2,3 +10420,1042,5,1,3 +10421,1042,6,2,4 +10422,1042,7,1,5 +10430,1043,15,1,4 +10431,1043,16,2,5 +10432,1043,17,1,6 +10433,1043,18,2,7 +10440,1044,4,1,5 +10450,1045,14,1,6 +10451,1045,15,2,7 +10460,1046,3,1,-9 +10461,1046,4,2,8 +10462,1046,5,1,9 +10470,1047,13,1,8 +10471,1047,14,2,-9 +10472,1047,15,1,10 +10473,1047,16,2,1 +10480,1048,2,1,9 +10490,1049,12,1,10 +10491,1049,13,2,1 10500,1050,1,1,1 10501,1050,2,2,2 10502,1050,3,1,3 -10510,1051,1,1,4 -10511,1051,2,2,5 -10512,1051,3,1,6 -10513,1051,4,2,7 -10520,1052,1,1,7 -10530,1053,1,1,3 -10531,1053,2,2,4 -10540,1054,1,1,6 -10541,1054,2,2,7 -10542,1054,3,1,1 -10550,1055,1,1,2 -10551,1055,2,2,3 -10552,1055,3,1,4 -10553,1055,4,2,5 -10560,1056,1,1,5 -10570,1057,1,1,1 -10571,1057,2,2,2 -10580,1058,1,1,4 -10581,1058,2,2,5 -10582,1058,3,1,6 -10590,1059,1,1,7 -10591,1059,2,2,1 -10592,1059,3,1,2 -10593,1059,4,2,3 -10600,1060,1,1,3 -10610,1061,1,1,6 -10611,1061,2,2,7 -10620,1062,1,1,2 -10621,1062,2,2,3 -10622,1062,3,1,4 -10630,1063,1,1,5 -10631,1063,2,2,6 -10632,1063,3,1,7 -10633,1063,4,2,1 +10510,1051,11,1,2 +10511,1051,12,2,3 +10512,1051,13,1,4 +10513,1051,14,2,5 +10520,1052,21,1,3 +10530,1053,10,1,4 +10531,1053,11,2,5 +10540,1054,20,1,5 +10541,1054,21,2,6 +10542,1054,1,1,7 +10550,1055,9,1,6 +10551,1055,10,2,7 +10552,1055,11,1,8 +10553,1055,12,2,9 +10560,1056,19,1,7 +10570,1057,8,1,-9 +10571,1057,9,2,9 +10580,1058,18,1,9 +10581,1058,19,2,-9 +10582,1058,20,1,1 +10590,1059,7,1,10 +10591,1059,8,2,1 +10592,1059,9,1,-9 +10593,1059,10,2,3 +10600,1060,17,1,1 +10610,1061,6,1,2 +10611,1061,7,2,3 +10620,1062,16,1,3 +10621,1062,17,2,4 +10622,1062,18,1,5 +10630,1063,5,1,4 +10631,1063,6,2,5 +10632,1063,7,1,6 +10633,1063,8,2,7 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv index c28d3e136..02dbabdae 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_trip.csv @@ -1,641 +1,717 @@ -TripID,IndividualID,HouseholdID,MainMode_B04ID,W5xHH,JJXSC +TripID,IndividualID,HouseholdID,MainMode_B04ID,W5,JJXSC 1,10000,1000,8,1,1 2,10000,1000,8,1.1000000000000001,1 -3,10000,1000,3,1,1 -4,10010,1001,8,1,1 -5,10010,1001,8,1.1000000000000001,1 -6,10010,1001,8,1.2,1 -7,10010,1001,8,1,1 -8,10010,1001,8,1.1000000000000001,1 -9,10010,1001,8,1.2,1 -10,10010,1001,3,1,1 -11,10011,1001,8,1,1 -12,10011,1001,8,1.1000000000000001,1 -13,10011,1001,8,1.2,1 -14,10011,1001,8,1,1 -15,10011,1001,8,1.1000000000000001,1 -16,10011,1001,3,1,1 -17,10020,1002,8,1,1 -18,10020,1002,8,1.1000000000000001,1 -19,10020,1002,8,1.2,1 -20,10020,1002,3,1,1 -21,10021,1002,8,1,1 -22,10021,1002,8,1.1000000000000001,1 -23,10021,1002,3,1,1 -24,10022,1002,8,1,1 -25,10022,1002,3,1,1 -26,10030,1003,3,1,1 -27,10031,1003,8,1,1 -28,10031,1003,8,1.1000000000000001,1 -29,10031,1003,8,1.2,1 -30,10031,1003,8,1,1 -31,10031,1003,8,1.1000000000000001,1 -32,10031,1003,8,1.2,1 -33,10031,1003,3,1,1 -34,10032,1003,8,1,1 -35,10032,1003,8,1.1000000000000001,1 -36,10032,1003,8,1.2,1 -37,10032,1003,8,1,1 -38,10032,1003,8,1.1000000000000001,1 -39,10032,1003,3,1,1 -40,10033,1003,8,1,1 -41,10033,1003,8,1.1000000000000001,1 -42,10033,1003,8,1.2,1 -43,10033,1003,8,1,1 -44,10033,1003,3,1,1 -45,10040,1004,8,1,1 -46,10040,1004,8,1.1000000000000001,1 -47,10040,1004,8,1.2,1 -48,10040,1004,8,1,1 -49,10040,1004,3,1,1 -50,10050,1005,8,1,1 -51,10050,1005,3,1,1 -52,10051,1005,3,1,1 -53,10060,1006,7,1,1 -54,10060,1006,7,1.1000000000000001,1 -55,10060,1006,7,1.2,1 -56,10060,1006,7,1,1 -57,10060,1006,7,1.1000000000000001,1 -58,10060,1006,3,1,1 -59,10061,1006,7,1,1 -60,10061,1006,7,1.1000000000000001,1 -61,10061,1006,7,1.2,1 -62,10061,1006,7,1,1 -63,10061,1006,3,1,1 -64,10062,1006,7,1,1 -65,10062,1006,7,1.1000000000000001,1 -66,10062,1006,7,1.2,1 -67,10062,1006,3,1,1 -68,10070,1007,8,1,1 -69,10070,1007,8,1.1000000000000001,1 +3,10000,1000,8,1.2,1 +4,10000,1000,8,1,1 +5,10000,1000,8,1.1000000000000001,1 +6,10000,1000,8,1.2,1 +7,10000,1000,8,1,1 +8,10000,1000,8,1.1000000000000001,1 +9,10000,1000,3,1,1 +10,10010,1001,8,1.1000000000000001,1 +11,10010,1001,8,1.2100000000000002,1 +12,10010,1001,8,1.3200000000000001,1 +13,10010,1001,8,1.1000000000000001,1 +14,10010,1001,8,1.2100000000000002,1 +15,10010,1001,8,1.3200000000000001,1 +16,10010,1001,8,1.1000000000000001,1 +17,10010,1001,3,1.1000000000000001,1 +18,10011,1001,8,1.1000000000000001,1 +19,10011,1001,8,1.2100000000000002,1 +20,10011,1001,8,1.3200000000000001,1 +21,10011,1001,8,1.1000000000000001,1 +22,10011,1001,8,1.2100000000000002,1 +23,10011,1001,8,1.3200000000000001,1 +24,10011,1001,3,1.1000000000000001,1 +25,10020,1002,3,1.2,1 +26,10021,1002,8,1.2,1 +27,10021,1002,8,1.3200000000000001,1 +28,10021,1002,8,1.4399999999999999,1 +29,10021,1002,8,1.2,1 +30,10021,1002,8,1.3200000000000001,1 +31,10021,1002,3,1.2,1 +32,10022,1002,8,1.2,1 +33,10022,1002,8,1.3200000000000001,1 +34,10022,1002,8,1.4399999999999999,1 +35,10022,1002,8,1.2,1 +36,10022,1002,3,1.2,1 +37,10030,1003,8,1.3,1 +38,10030,1003,8,1.4300000000000002,1 +39,10030,1003,8,1.5600000000000001,1 +40,10030,1003,8,1.3,1 +41,10030,1003,8,1.4300000000000002,1 +42,10030,1003,3,1.3,1 +43,10031,1003,3,1.3,1 +44,10032,1003,8,1.3,1 +45,10032,1003,8,1.4300000000000002,1 +46,10032,1003,8,1.5600000000000001,1 +47,10032,1003,3,1.3,1 +48,10033,1003,8,1.3,1 +49,10033,1003,8,1.4300000000000002,1 +50,10033,1003,3,1.3,1 +51,10040,1004,8,1.3999999999999999,1 +52,10040,1004,8,1.54,1 +53,10040,1004,8,1.6799999999999999,1 +54,10040,1004,8,1.3999999999999999,1 +55,10040,1004,3,1.3999999999999999,1 +56,10050,1005,8,1.5,1 +57,10050,1005,8,1.6500000000000001,1 +58,10050,1005,8,1.7999999999999998,1 +59,10050,1005,3,1.5,1 +60,10051,1005,8,1.5,1 +61,10051,1005,8,1.6500000000000001,1 +62,10051,1005,3,1.5,1 +63,10060,1006,7,1.6000000000000001,1 +64,10060,1006,7,1.7600000000000002,1 +65,10060,1006,3,1.6000000000000001,1 +66,10061,1006,7,1.6000000000000001,1 +67,10061,1006,3,1.6000000000000001,1 +68,10062,1006,3,1.6000000000000001,1 +69,10070,1007,8,1,1 70,10070,1007,3,1,1 -71,10071,1007,8,1,1 -72,10071,1007,3,1,1 -73,10072,1007,3,1,1 -74,10073,1007,8,1,1 -75,10073,1007,8,1.1000000000000001,1 -76,10073,1007,8,1.2,1 -77,10073,1007,8,1,1 -78,10073,1007,8,1.1000000000000001,1 -79,10073,1007,8,1.2,1 -80,10073,1007,3,1,1 -81,10080,1008,8,1,1 -82,10080,1008,8,1.1000000000000001,1 -83,10080,1008,8,1.2,1 -84,10080,1008,8,1,1 -85,10080,1008,8,1.1000000000000001,1 -86,10080,1008,8,1.2,1 -87,10080,1008,3,1,1 -88,10090,1009,8,1,1 -89,10090,1009,8,1.1000000000000001,1 -90,10090,1009,8,1.2,1 -91,10090,1009,3,1,1 -92,10091,1009,8,1,1 -93,10091,1009,8,1.1000000000000001,1 -94,10091,1009,3,1,1 -95,10100,1010,3,1,1 -96,10101,1010,8,1,1 -97,10101,1010,8,1.1000000000000001,1 -98,10101,1010,8,1.2,1 -99,10101,1010,8,1,1 -100,10101,1010,8,1.1000000000000001,1 -101,10101,1010,8,1.2,1 -102,10101,1010,3,1,1 -103,10102,1010,8,1,1 -104,10102,1010,8,1.1000000000000001,1 -105,10102,1010,8,1.2,1 -106,10102,1010,8,1,1 -107,10102,1010,8,1.1000000000000001,1 -108,10102,1010,3,1,1 -109,10110,1011,8,1,1 -110,10110,1011,8,1.1000000000000001,1 -111,10110,1011,8,1.2,1 -112,10110,1011,8,1,1 -113,10110,1011,3,1,1 -114,10111,1011,8,1,1 -115,10111,1011,8,1.1000000000000001,1 -116,10111,1011,8,1.2,1 -117,10111,1011,3,1,1 -118,10112,1011,8,1,1 -119,10112,1011,8,1.1000000000000001,1 -120,10112,1011,3,1,1 -121,10113,1011,8,1,1 -122,10113,1011,3,1,1 -123,10120,1012,8,1,1 -124,10120,1012,3,1,1 -125,10130,1013,8,1,1 -126,10130,1013,8,1.1000000000000001,1 -127,10130,1013,8,1.2,1 -128,10130,1013,8,1,1 -129,10130,1013,8,1.1000000000000001,1 -130,10130,1013,3,1,1 -131,10131,1013,8,1,1 -132,10131,1013,8,1.1000000000000001,1 -133,10131,1013,8,1.2,1 -134,10131,1013,8,1,1 -135,10131,1013,3,1,1 -136,10140,1014,8,1,1 -137,10140,1014,8,1.1000000000000001,1 -138,10140,1014,3,1,1 -139,10141,1014,8,1,1 -140,10141,1014,3,1,1 -141,10142,1014,3,1,1 -142,10150,1015,7,1,1 -143,10150,1015,7,1.1000000000000001,1 -144,10150,1015,7,1.2,1 -145,10150,1015,7,1,1 -146,10150,1015,7,1.1000000000000001,1 -147,10150,1015,7,1.2,1 -148,10150,1015,3,1,1 -149,10151,1015,7,1,1 -150,10151,1015,7,1.1000000000000001,1 -151,10151,1015,7,1.2,1 -152,10151,1015,7,1,1 -153,10151,1015,7,1.1000000000000001,1 -154,10151,1015,3,1,1 -155,10152,1015,7,1,1 -156,10152,1015,7,1.1000000000000001,1 -157,10152,1015,7,1.2,1 -158,10152,1015,7,1,1 -159,10152,1015,3,1,1 -160,10153,1015,7,1,1 -161,10153,1015,7,1.1000000000000001,1 -162,10153,1015,7,1.2,1 -163,10153,1015,3,1,1 -164,10160,1016,8,1,1 -165,10160,1016,8,1.1000000000000001,1 -166,10160,1016,8,1.2,1 -167,10160,1016,3,1,1 -168,10170,1017,3,1,1 -169,10171,1017,8,1,1 -170,10171,1017,8,1.1000000000000001,1 -171,10171,1017,8,1.2,1 -172,10171,1017,8,1,1 -173,10171,1017,8,1.1000000000000001,1 -174,10171,1017,8,1.2,1 -175,10171,1017,3,1,1 -176,10180,1018,8,1,1 -177,10180,1018,8,1.1000000000000001,1 -178,10180,1018,8,1.2,1 -179,10180,1018,8,1,1 -180,10180,1018,3,1,1 -181,10181,1018,8,1,1 -182,10181,1018,8,1.1000000000000001,1 -183,10181,1018,8,1.2,1 -184,10181,1018,3,1,1 -185,10182,1018,8,1,1 -186,10182,1018,8,1.1000000000000001,1 -187,10182,1018,3,1,1 -188,10190,1019,8,1,1 -189,10190,1019,3,1,1 -190,10191,1019,3,1,1 -191,10192,1019,8,1,1 -192,10192,1019,8,1.1000000000000001,1 -193,10192,1019,8,1.2,1 -194,10192,1019,8,1,1 -195,10192,1019,8,1.1000000000000001,1 -196,10192,1019,8,1.2,1 -197,10192,1019,3,1,1 -198,10193,1019,8,1,1 -199,10193,1019,8,1.1000000000000001,1 -200,10193,1019,8,1.2,1 -201,10193,1019,8,1,1 -202,10193,1019,8,1.1000000000000001,1 -203,10193,1019,3,1,1 -204,10200,1020,8,1,1 -205,10200,1020,8,1.1000000000000001,1 -206,10200,1020,8,1.2,1 -207,10200,1020,8,1,1 -208,10200,1020,8,1.1000000000000001,1 -209,10200,1020,3,1,1 -210,10210,1021,8,1,1 -211,10210,1021,8,1.1000000000000001,1 -212,10210,1021,3,1,1 -213,10211,1021,8,1,1 -214,10211,1021,3,1,1 -215,10220,1022,8,1,1 -216,10220,1022,8,1.1000000000000001,1 -217,10220,1022,8,1.2,1 -218,10220,1022,8,1,1 -219,10220,1022,8,1.1000000000000001,1 -220,10220,1022,8,1.2,1 -221,10220,1022,3,1,1 -222,10221,1022,8,1,1 -223,10221,1022,8,1.1000000000000001,1 -224,10221,1022,8,1.2,1 -225,10221,1022,8,1,1 -226,10221,1022,8,1.1000000000000001,1 -227,10221,1022,3,1,1 -228,10222,1022,8,1,1 -229,10222,1022,8,1.1000000000000001,1 -230,10222,1022,8,1.2,1 -231,10222,1022,8,1,1 -232,10222,1022,3,1,1 -233,10230,1023,8,1,1 -234,10230,1023,8,1.1000000000000001,1 -235,10230,1023,8,1.2,1 -236,10230,1023,3,1,1 -237,10231,1023,8,1,1 -238,10231,1023,8,1.1000000000000001,1 -239,10231,1023,3,1,1 -240,10232,1023,8,1,1 -241,10232,1023,3,1,1 -242,10233,1023,3,1,1 -243,10240,1024,3,1,1 -244,10250,1025,8,1,1 -245,10250,1025,8,1.1000000000000001,1 -246,10250,1025,8,1.2,1 -247,10250,1025,8,1,1 -248,10250,1025,3,1,1 -249,10251,1025,8,1,1 -250,10251,1025,8,1.1000000000000001,1 -251,10251,1025,8,1.2,1 -252,10251,1025,3,1,1 -253,10260,1026,8,1,1 -254,10260,1026,3,1,1 -255,10261,1026,3,1,1 -256,10262,1026,8,1,1 -257,10262,1026,8,1.1000000000000001,1 -258,10262,1026,8,1.2,1 -259,10262,1026,8,1,1 -260,10262,1026,8,1.1000000000000001,1 -261,10262,1026,8,1.2,1 -262,10262,1026,3,1,1 -263,10270,1027,8,1,1 -264,10270,1027,8,1.1000000000000001,1 -265,10270,1027,8,1.2,1 -266,10270,1027,8,1,1 -267,10270,1027,8,1.1000000000000001,1 -268,10270,1027,3,1,1 -269,10271,1027,8,1,1 -270,10271,1027,8,1.1000000000000001,1 -271,10271,1027,8,1.2,1 -272,10271,1027,8,1,1 -273,10271,1027,3,1,1 -274,10272,1027,8,1,1 -275,10272,1027,8,1.1000000000000001,1 -276,10272,1027,8,1.2,1 -277,10272,1027,3,1,1 -278,10273,1027,8,1,1 -279,10273,1027,8,1.1000000000000001,1 -280,10273,1027,3,1,1 -281,10280,1028,8,1,1 -282,10280,1028,8,1.1000000000000001,1 -283,10280,1028,3,1,1 -284,10290,1029,8,1,1 -285,10290,1029,8,1.1000000000000001,1 -286,10290,1029,8,1.2,1 -287,10290,1029,8,1,1 -288,10290,1029,8,1.1000000000000001,1 -289,10290,1029,8,1.2,1 -290,10290,1029,3,1,1 -291,10291,1029,8,1,1 -292,10291,1029,8,1.1000000000000001,1 -293,10291,1029,8,1.2,1 -294,10291,1029,8,1,1 +71,10071,1007,3,1,1 +72,10072,1007,3,1,1 +73,10073,1007,8,1,1 +74,10073,1007,8,1.1000000000000001,1 +75,10073,1007,8,1.2,1 +76,10073,1007,8,1,1 +77,10073,1007,8,1.1000000000000001,1 +78,10073,1007,8,1.2,1 +79,10073,1007,8,1,1 +80,10073,1007,8,1.1000000000000001,1 +81,10073,1007,3,1,1 +82,10080,1008,3,1.1000000000000001,1 +83,10090,1009,3,1.2,1 +84,10091,1009,8,1.2,1 +85,10091,1009,8,1.3200000000000001,1 +86,10091,1009,8,1.4399999999999999,1 +87,10091,1009,8,1.2,1 +88,10091,1009,8,1.3200000000000001,1 +89,10091,1009,8,1.4399999999999999,1 +90,10091,1009,8,1.2,1 +91,10091,1009,8,1.3200000000000001,1 +92,10091,1009,3,1.2,1 +93,10100,1010,8,1.3,1 +94,10100,1010,8,1.4300000000000002,1 +95,10100,1010,8,1.5600000000000001,1 +96,10100,1010,8,1.3,1 +97,10100,1010,8,1.4300000000000002,1 +98,10100,1010,8,1.5600000000000001,1 +99,10100,1010,8,1.3,1 +100,10100,1010,8,1.4300000000000002,1 +101,10100,1010,3,1.3,1 +102,10101,1010,8,1.3,1 +103,10101,1010,8,1.4300000000000002,1 +104,10101,1010,8,1.5600000000000001,1 +105,10101,1010,8,1.3,1 +106,10101,1010,8,1.4300000000000002,1 +107,10101,1010,8,1.5600000000000001,1 +108,10101,1010,8,1.3,1 +109,10101,1010,3,1.3,1 +110,10102,1010,8,1.3,1 +111,10102,1010,8,1.4300000000000002,1 +112,10102,1010,8,1.5600000000000001,1 +113,10102,1010,8,1.3,1 +114,10102,1010,8,1.4300000000000002,1 +115,10102,1010,8,1.5600000000000001,1 +116,10102,1010,3,1.3,1 +117,10110,1011,8,1.3999999999999999,1 +118,10110,1011,8,1.54,1 +119,10110,1011,8,1.6799999999999999,1 +120,10110,1011,8,1.3999999999999999,1 +121,10110,1011,8,1.54,1 +122,10110,1011,8,1.6799999999999999,1 +123,10110,1011,8,1.3999999999999999,1 +124,10110,1011,3,1.3999999999999999,1 +125,10111,1011,8,1.3999999999999999,1 +126,10111,1011,8,1.54,1 +127,10111,1011,8,1.6799999999999999,1 +128,10111,1011,8,1.3999999999999999,1 +129,10111,1011,8,1.54,1 +130,10111,1011,8,1.6799999999999999,1 +131,10111,1011,3,1.3999999999999999,1 +132,10112,1011,8,1.3999999999999999,1 +133,10112,1011,8,1.54,1 +134,10112,1011,8,1.6799999999999999,1 +135,10112,1011,8,1.3999999999999999,1 +136,10112,1011,8,1.54,1 +137,10112,1011,3,1.3999999999999999,1 +138,10113,1011,8,1.3999999999999999,1 +139,10113,1011,8,1.54,1 +140,10113,1011,8,1.6799999999999999,1 +141,10113,1011,8,1.3999999999999999,1 +142,10113,1011,3,1.3999999999999999,1 +143,10120,1012,8,1.5,1 +144,10120,1012,8,1.6500000000000001,1 +145,10120,1012,8,1.7999999999999998,1 +146,10120,1012,8,1.5,1 +147,10120,1012,8,1.6500000000000001,1 +148,10120,1012,8,1.7999999999999998,1 +149,10120,1012,3,1.5,1 +150,10130,1013,3,1.6000000000000001,1 +151,10131,1013,8,1.6000000000000001,1 +152,10131,1013,8,1.7600000000000002,1 +153,10131,1013,8,1.9199999999999999,1 +154,10131,1013,8,1.6000000000000001,1 +155,10131,1013,3,1.6000000000000001,1 +156,10140,1014,8,1,1 +157,10140,1014,8,1.1000000000000001,1 +158,10140,1014,8,1.2,1 +159,10140,1014,8,1,1 +160,10140,1014,3,1,1 +161,10141,1014,3,1,1 +162,10142,1014,8,1,1 +163,10142,1014,8,1.1000000000000001,1 +164,10142,1014,3,1,1 +165,10150,1015,7,1.1000000000000001,1 +166,10150,1015,7,1.2100000000000002,1 +167,10150,1015,7,1.3200000000000001,1 +168,10150,1015,3,1.1000000000000001,1 +169,10151,1015,7,1.1000000000000001,1 +170,10151,1015,7,1.2100000000000002,1 +171,10151,1015,3,1.1000000000000001,1 +172,10152,1015,3,1.1000000000000001,1 +173,10153,1015,3,1.1000000000000001,1 +174,10160,1016,8,1.2,1 +175,10160,1016,8,1.3200000000000001,1 +176,10160,1016,3,1.2,1 +177,10170,1017,8,1.3,1 +178,10170,1017,3,1.3,1 +179,10171,1017,3,1.3,1 +180,10180,1018,3,1.3999999999999999,1 +181,10181,1018,3,1.3999999999999999,1 +182,10182,1018,8,1.3999999999999999,1 +183,10182,1018,8,1.54,1 +184,10182,1018,8,1.6799999999999999,1 +185,10182,1018,8,1.3999999999999999,1 +186,10182,1018,8,1.54,1 +187,10182,1018,8,1.6799999999999999,1 +188,10182,1018,8,1.3999999999999999,1 +189,10182,1018,8,1.54,1 +190,10182,1018,3,1.3999999999999999,1 +191,10190,1019,3,1.5,1 +192,10191,1019,8,1.5,1 +193,10191,1019,8,1.6500000000000001,1 +194,10191,1019,8,1.7999999999999998,1 +195,10191,1019,8,1.5,1 +196,10191,1019,8,1.6500000000000001,1 +197,10191,1019,8,1.7999999999999998,1 +198,10191,1019,8,1.5,1 +199,10191,1019,8,1.6500000000000001,1 +200,10191,1019,3,1.5,1 +201,10192,1019,8,1.5,1 +202,10192,1019,8,1.6500000000000001,1 +203,10192,1019,8,1.7999999999999998,1 +204,10192,1019,8,1.5,1 +205,10192,1019,8,1.6500000000000001,1 +206,10192,1019,8,1.7999999999999998,1 +207,10192,1019,8,1.5,1 +208,10192,1019,3,1.5,1 +209,10193,1019,8,1.5,1 +210,10193,1019,8,1.6500000000000001,1 +211,10193,1019,8,1.7999999999999998,1 +212,10193,1019,8,1.5,1 +213,10193,1019,8,1.6500000000000001,1 +214,10193,1019,8,1.7999999999999998,1 +215,10193,1019,3,1.5,1 +216,10200,1020,8,1.6000000000000001,1 +217,10200,1020,8,1.7600000000000002,1 +218,10200,1020,8,1.9199999999999999,1 +219,10200,1020,8,1.6000000000000001,1 +220,10200,1020,8,1.7600000000000002,1 +221,10200,1020,8,1.9199999999999999,1 +222,10200,1020,8,1.6000000000000001,1 +223,10200,1020,8,1.7600000000000002,1 +224,10200,1020,3,1.6000000000000001,1 +225,10210,1021,8,1,1 +226,10210,1021,8,1.1000000000000001,1 +227,10210,1021,8,1.2,1 +228,10210,1021,8,1,1 +229,10210,1021,8,1.1000000000000001,1 +230,10210,1021,8,1.2,1 +231,10210,1021,8,1,1 +232,10210,1021,3,1,1 +233,10211,1021,8,1,1 +234,10211,1021,8,1.1000000000000001,1 +235,10211,1021,8,1.2,1 +236,10211,1021,8,1,1 +237,10211,1021,8,1.1000000000000001,1 +238,10211,1021,8,1.2,1 +239,10211,1021,3,1,1 +240,10220,1022,8,1.1000000000000001,1 +241,10220,1022,8,1.2100000000000002,1 +242,10220,1022,8,1.3200000000000001,1 +243,10220,1022,8,1.1000000000000001,1 +244,10220,1022,8,1.2100000000000002,1 +245,10220,1022,8,1.3200000000000001,1 +246,10220,1022,3,1.1000000000000001,1 +247,10221,1022,8,1.1000000000000001,1 +248,10221,1022,8,1.2100000000000002,1 +249,10221,1022,8,1.3200000000000001,1 +250,10221,1022,8,1.1000000000000001,1 +251,10221,1022,8,1.2100000000000002,1 +252,10221,1022,3,1.1000000000000001,1 +253,10222,1022,8,1.1000000000000001,1 +254,10222,1022,8,1.2100000000000002,1 +255,10222,1022,8,1.3200000000000001,1 +256,10222,1022,8,1.1000000000000001,1 +257,10222,1022,3,1.1000000000000001,1 +258,10230,1023,8,1.2,1 +259,10230,1023,8,1.3200000000000001,1 +260,10230,1023,8,1.4399999999999999,1 +261,10230,1023,8,1.2,1 +262,10230,1023,8,1.3200000000000001,1 +263,10230,1023,3,1.2,1 +264,10231,1023,8,1.2,1 +265,10231,1023,8,1.3200000000000001,1 +266,10231,1023,8,1.4399999999999999,1 +267,10231,1023,8,1.2,1 +268,10231,1023,3,1.2,1 +269,10232,1023,8,1.2,1 +270,10232,1023,8,1.3200000000000001,1 +271,10232,1023,8,1.4399999999999999,1 +272,10232,1023,3,1.2,1 +273,10233,1023,8,1.2,1 +274,10233,1023,8,1.3200000000000001,1 +275,10233,1023,3,1.2,1 +276,10240,1024,3,1.3,1 +277,10250,1025,8,1.3999999999999999,1 +278,10250,1025,8,1.54,1 +279,10250,1025,8,1.6799999999999999,1 +280,10250,1025,3,1.3999999999999999,1 +281,10251,1025,3,1.3999999999999999,1 +282,10260,1026,8,1.5,1 +283,10260,1026,8,1.6500000000000001,1 +284,10260,1026,3,1.5,1 +285,10261,1026,8,1.5,1 +286,10261,1026,3,1.5,1 +287,10262,1026,3,1.5,1 +288,10270,1027,8,1.6000000000000001,1 +289,10270,1027,3,1.6000000000000001,1 +290,10271,1027,3,1.6000000000000001,1 +291,10272,1027,3,1.6000000000000001,1 +292,10273,1027,3,1.6000000000000001,1 +293,10280,1028,3,1,1 +294,10290,1029,3,1.1000000000000001,1 295,10291,1029,8,1.1000000000000001,1 -296,10291,1029,3,1,1 -297,10300,1030,8,1,1 -298,10300,1030,8,1.1000000000000001,1 -299,10300,1030,8,1.2,1 -300,10300,1030,3,1,1 -301,10301,1030,8,1,1 -302,10301,1030,8,1.1000000000000001,1 -303,10301,1030,3,1,1 -304,10302,1030,8,1,1 -305,10302,1030,3,1,1 -306,10310,1031,3,1,1 -307,10311,1031,8,1,1 -308,10311,1031,8,1.1000000000000001,1 -309,10311,1031,8,1.2,1 -310,10311,1031,8,1,1 -311,10311,1031,8,1.1000000000000001,1 -312,10311,1031,8,1.2,1 -313,10311,1031,3,1,1 -314,10312,1031,8,1,1 -315,10312,1031,8,1.1000000000000001,1 -316,10312,1031,8,1.2,1 -317,10312,1031,8,1,1 -318,10312,1031,8,1.1000000000000001,1 -319,10312,1031,3,1,1 -320,10313,1031,8,1,1 -321,10313,1031,8,1.1000000000000001,1 -322,10313,1031,8,1.2,1 -323,10313,1031,8,1,1 -324,10313,1031,3,1,1 -325,10320,1032,8,1,1 -326,10320,1032,8,1.1000000000000001,1 -327,10320,1032,8,1.2,1 -328,10320,1032,8,1,1 -329,10320,1032,3,1,1 -330,10330,1033,7,1,1 -331,10330,1033,3,1,1 -332,10331,1033,3,1,1 -333,10340,1034,8,1,1 -334,10340,1034,8,1.1000000000000001,1 -335,10340,1034,8,1.2,1 -336,10340,1034,8,1,1 -337,10340,1034,8,1.1000000000000001,1 -338,10340,1034,3,1,1 -339,10341,1034,8,1,1 -340,10341,1034,8,1.1000000000000001,1 -341,10341,1034,8,1.2,1 -342,10341,1034,8,1,1 -343,10341,1034,3,1,1 -344,10342,1034,8,1,1 -345,10342,1034,8,1.1000000000000001,1 -346,10342,1034,8,1.2,1 -347,10342,1034,3,1,1 -348,10350,1035,8,1,1 -349,10350,1035,8,1.1000000000000001,1 -350,10350,1035,3,1,1 -351,10351,1035,8,1,1 -352,10351,1035,3,1,1 -353,10352,1035,3,1,1 -354,10353,1035,8,1,1 -355,10353,1035,8,1.1000000000000001,1 -356,10353,1035,8,1.2,1 -357,10353,1035,8,1,1 -358,10353,1035,8,1.1000000000000001,1 -359,10353,1035,8,1.2,1 -360,10353,1035,3,1,1 -361,10360,1036,8,1,1 -362,10360,1036,8,1.1000000000000001,1 -363,10360,1036,8,1.2,1 -364,10360,1036,8,1,1 -365,10360,1036,8,1.1000000000000001,1 -366,10360,1036,8,1.2,1 -367,10360,1036,3,1,1 -368,10370,1037,8,1,1 -369,10370,1037,8,1.1000000000000001,1 -370,10370,1037,8,1.2,1 -371,10370,1037,3,1,1 -372,10371,1037,8,1,1 -373,10371,1037,8,1.1000000000000001,1 -374,10371,1037,3,1,1 -375,10380,1038,3,1,1 -376,10381,1038,8,1,1 -377,10381,1038,8,1.1000000000000001,1 -378,10381,1038,8,1.2,1 -379,10381,1038,8,1,1 -380,10381,1038,8,1.1000000000000001,1 -381,10381,1038,8,1.2,1 -382,10381,1038,3,1,1 -383,10382,1038,8,1,1 -384,10382,1038,8,1.1000000000000001,1 -385,10382,1038,8,1.2,1 -386,10382,1038,8,1,1 -387,10382,1038,8,1.1000000000000001,1 -388,10382,1038,3,1,1 -389,10390,1039,8,1,1 -390,10390,1039,8,1.1000000000000001,1 -391,10390,1039,8,1.2,1 -392,10390,1039,8,1,1 -393,10390,1039,3,1,1 -394,10391,1039,8,1,1 -395,10391,1039,8,1.1000000000000001,1 -396,10391,1039,8,1.2,1 -397,10391,1039,3,1,1 -398,10392,1039,8,1,1 -399,10392,1039,8,1.1000000000000001,1 -400,10392,1039,3,1,1 -401,10393,1039,8,1,1 -402,10393,1039,3,1,1 -403,10400,1040,8,1,1 -404,10400,1040,3,1,1 -405,10410,1041,8,1,1 -406,10410,1041,8,1.1000000000000001,1 -407,10410,1041,8,1.2,1 -408,10410,1041,8,1,1 -409,10410,1041,8,1.1000000000000001,1 -410,10410,1041,3,1,1 -411,10411,1041,8,1,1 -412,10411,1041,8,1.1000000000000001,1 -413,10411,1041,8,1.2,1 -414,10411,1041,8,1,1 -415,10411,1041,3,1,1 -416,10420,1042,7,1,1 -417,10420,1042,7,1.1000000000000001,1 -418,10420,1042,3,1,1 -419,10421,1042,7,1,1 -420,10421,1042,3,1,1 -421,10422,1042,3,1,1 -422,10430,1043,8,1,1 -423,10430,1043,8,1.1000000000000001,1 -424,10430,1043,8,1.2,1 -425,10430,1043,8,1,1 -426,10430,1043,8,1.1000000000000001,1 -427,10430,1043,8,1.2,1 -428,10430,1043,3,1,1 -429,10431,1043,8,1,1 -430,10431,1043,8,1.1000000000000001,1 -431,10431,1043,8,1.2,1 -432,10431,1043,8,1,1 -433,10431,1043,8,1.1000000000000001,1 -434,10431,1043,3,1,1 -435,10432,1043,8,1,1 -436,10432,1043,8,1.1000000000000001,1 -437,10432,1043,8,1.2,1 -438,10432,1043,8,1,1 -439,10432,1043,3,1,1 -440,10433,1043,8,1,1 -441,10433,1043,8,1.1000000000000001,1 -442,10433,1043,8,1.2,1 -443,10433,1043,3,1,1 -444,10440,1044,8,1,1 -445,10440,1044,8,1.1000000000000001,1 -446,10440,1044,8,1.2,1 -447,10440,1044,3,1,1 -448,10450,1045,3,1,1 -449,10451,1045,8,1,1 -450,10451,1045,8,1.1000000000000001,1 -451,10451,1045,8,1.2,1 -452,10451,1045,8,1,1 -453,10451,1045,8,1.1000000000000001,1 -454,10451,1045,8,1.2,1 -455,10451,1045,3,1,1 -456,10460,1046,8,1,1 -457,10460,1046,8,1.1000000000000001,1 -458,10460,1046,8,1.2,1 -459,10460,1046,8,1,1 -460,10460,1046,3,1,1 -461,10461,1046,8,1,1 -462,10461,1046,8,1.1000000000000001,1 -463,10461,1046,8,1.2,1 -464,10461,1046,3,1,1 -465,10462,1046,8,1,1 -466,10462,1046,8,1.1000000000000001,1 -467,10462,1046,3,1,1 -468,10470,1047,8,1,1 -469,10470,1047,3,1,1 -470,10471,1047,3,1,1 -471,10472,1047,8,1,1 -472,10472,1047,8,1.1000000000000001,1 -473,10472,1047,8,1.2,1 -474,10472,1047,8,1,1 -475,10472,1047,8,1.1000000000000001,1 -476,10472,1047,8,1.2,1 -477,10472,1047,3,1,1 -478,10473,1047,8,1,1 -479,10473,1047,8,1.1000000000000001,1 -480,10473,1047,8,1.2,1 -481,10473,1047,8,1,1 -482,10473,1047,8,1.1000000000000001,1 -483,10473,1047,3,1,1 -484,10480,1048,8,1,1 -485,10480,1048,8,1.1000000000000001,1 -486,10480,1048,8,1.2,1 -487,10480,1048,8,1,1 -488,10480,1048,8,1.1000000000000001,1 -489,10480,1048,3,1,1 -490,10490,1049,8,1,1 -491,10490,1049,8,1.1000000000000001,1 -492,10490,1049,3,1,1 -493,10491,1049,8,1,1 -494,10491,1049,3,1,1 -495,10500,1050,8,1,1 -496,10500,1050,8,1.1000000000000001,1 -497,10500,1050,8,1.2,1 -498,10500,1050,8,1,1 -499,10500,1050,8,1.1000000000000001,1 -500,10500,1050,8,1.2,1 -501,10500,1050,3,1,1 -502,10501,1050,8,1,1 -503,10501,1050,8,1.1000000000000001,1 -504,10501,1050,8,1.2,1 -505,10501,1050,8,1,1 -506,10501,1050,8,1.1000000000000001,1 -507,10501,1050,3,1,1 -508,10502,1050,8,1,1 -509,10502,1050,8,1.1000000000000001,1 -510,10502,1050,8,1.2,1 -511,10502,1050,8,1,1 -512,10502,1050,3,1,1 -513,10510,1051,7,1,1 -514,10510,1051,7,1.1000000000000001,1 -515,10510,1051,7,1.2,1 -516,10510,1051,3,1,1 -517,10511,1051,7,1,1 -518,10511,1051,7,1.1000000000000001,1 -519,10511,1051,3,1,1 -520,10512,1051,7,1,1 -521,10512,1051,3,1,1 -522,10513,1051,3,1,1 -523,10520,1052,3,1,1 -524,10530,1053,8,1,1 -525,10530,1053,8,1.1000000000000001,1 -526,10530,1053,8,1.2,1 -527,10530,1053,8,1,1 -528,10530,1053,3,1,1 -529,10531,1053,8,1,1 -530,10531,1053,8,1.1000000000000001,1 -531,10531,1053,8,1.2,1 -532,10531,1053,3,1,1 -533,10540,1054,8,1,1 -534,10540,1054,3,1,1 -535,10541,1054,3,1,1 -536,10542,1054,8,1,1 -537,10542,1054,8,1.1000000000000001,1 -538,10542,1054,8,1.2,1 -539,10542,1054,8,1,1 -540,10542,1054,8,1.1000000000000001,1 -541,10542,1054,8,1.2,1 -542,10542,1054,3,1,1 -543,10550,1055,8,1,1 -544,10550,1055,8,1.1000000000000001,1 -545,10550,1055,8,1.2,1 -546,10550,1055,8,1,1 -547,10550,1055,8,1.1000000000000001,1 -548,10550,1055,3,1,1 -549,10551,1055,8,1,1 -550,10551,1055,8,1.1000000000000001,1 -551,10551,1055,8,1.2,1 -552,10551,1055,8,1,1 -553,10551,1055,3,1,1 -554,10552,1055,8,1,1 -555,10552,1055,8,1.1000000000000001,1 -556,10552,1055,8,1.2,1 -557,10552,1055,3,1,1 -558,10553,1055,8,1,1 -559,10553,1055,8,1.1000000000000001,1 -560,10553,1055,3,1,1 -561,10560,1056,8,1,1 -562,10560,1056,8,1.1000000000000001,1 -563,10560,1056,3,1,1 -564,10570,1057,8,1,1 -565,10570,1057,8,1.1000000000000001,1 -566,10570,1057,8,1.2,1 -567,10570,1057,8,1,1 -568,10570,1057,8,1.1000000000000001,1 -569,10570,1057,8,1.2,1 -570,10570,1057,3,1,1 -571,10571,1057,8,1,1 -572,10571,1057,8,1.1000000000000001,1 -573,10571,1057,8,1.2,1 -574,10571,1057,8,1,1 -575,10571,1057,8,1.1000000000000001,1 -576,10571,1057,3,1,1 -577,10580,1058,8,1,1 -578,10580,1058,8,1.1000000000000001,1 -579,10580,1058,8,1.2,1 -580,10580,1058,3,1,1 -581,10581,1058,8,1,1 -582,10581,1058,8,1.1000000000000001,1 -583,10581,1058,3,1,1 -584,10582,1058,8,1,1 -585,10582,1058,3,1,1 -586,10590,1059,3,1,1 -587,10591,1059,8,1,1 -588,10591,1059,8,1.1000000000000001,1 -589,10591,1059,8,1.2,1 -590,10591,1059,8,1,1 -591,10591,1059,8,1.1000000000000001,1 -592,10591,1059,8,1.2,1 -593,10591,1059,3,1,1 -594,10592,1059,8,1,1 -595,10592,1059,8,1.1000000000000001,1 -596,10592,1059,8,1.2,1 -597,10592,1059,8,1,1 -598,10592,1059,8,1.1000000000000001,1 -599,10592,1059,3,1,1 -600,10593,1059,8,1,1 -601,10593,1059,8,1.1000000000000001,1 -602,10593,1059,8,1.2,1 -603,10593,1059,8,1,1 -604,10593,1059,3,1,1 -605,10600,1060,7,1,1 -606,10600,1060,7,1.1000000000000001,1 -607,10600,1060,7,1.2,1 -608,10600,1060,7,1,1 -609,10600,1060,3,1,1 -610,10610,1061,8,1,1 -611,10610,1061,3,1,1 -612,10611,1061,3,1,1 -613,10620,1062,8,1,1 -614,10620,1062,8,1.1000000000000001,1 -615,10620,1062,8,1.2,1 -616,10620,1062,8,1,1 -617,10620,1062,8,1.1000000000000001,1 -618,10620,1062,3,1,1 -619,10621,1062,8,1,1 -620,10621,1062,8,1.1000000000000001,1 -621,10621,1062,8,1.2,1 -622,10621,1062,8,1,1 -623,10621,1062,3,1,1 -624,10622,1062,8,1,1 -625,10622,1062,8,1.1000000000000001,1 -626,10622,1062,8,1.2,1 -627,10622,1062,3,1,1 -628,10630,1063,8,1,1 -629,10630,1063,8,1.1000000000000001,1 -630,10630,1063,3,1,1 -631,10631,1063,8,1,1 -632,10631,1063,3,1,1 -633,10632,1063,3,1,1 -634,10633,1063,8,1,1 -635,10633,1063,8,1.1000000000000001,1 -636,10633,1063,8,1.2,1 -637,10633,1063,8,1,1 -638,10633,1063,8,1.1000000000000001,1 -639,10633,1063,8,1.2,1 -640,10633,1063,3,1,1 +296,10291,1029,8,1.2100000000000002,1 +297,10291,1029,8,1.3200000000000001,1 +298,10291,1029,8,1.1000000000000001,1 +299,10291,1029,8,1.2100000000000002,1 +300,10291,1029,8,1.3200000000000001,1 +301,10291,1029,8,1.1000000000000001,1 +302,10291,1029,8,1.2100000000000002,1 +303,10291,1029,3,1.1000000000000001,1 +304,10300,1030,8,1.2,1 +305,10300,1030,8,1.3200000000000001,1 +306,10300,1030,8,1.4399999999999999,1 +307,10300,1030,8,1.2,1 +308,10300,1030,8,1.3200000000000001,1 +309,10300,1030,8,1.4399999999999999,1 +310,10300,1030,8,1.2,1 +311,10300,1030,8,1.3200000000000001,1 +312,10300,1030,3,1.2,1 +313,10301,1030,8,1.2,1 +314,10301,1030,8,1.3200000000000001,1 +315,10301,1030,8,1.4399999999999999,1 +316,10301,1030,8,1.2,1 +317,10301,1030,8,1.3200000000000001,1 +318,10301,1030,8,1.4399999999999999,1 +319,10301,1030,8,1.2,1 +320,10301,1030,3,1.2,1 +321,10302,1030,8,1.2,1 +322,10302,1030,8,1.3200000000000001,1 +323,10302,1030,8,1.4399999999999999,1 +324,10302,1030,8,1.2,1 +325,10302,1030,8,1.3200000000000001,1 +326,10302,1030,8,1.4399999999999999,1 +327,10302,1030,3,1.2,1 +328,10310,1031,8,1.3,1 +329,10310,1031,8,1.4300000000000002,1 +330,10310,1031,8,1.5600000000000001,1 +331,10310,1031,8,1.3,1 +332,10310,1031,8,1.4300000000000002,1 +333,10310,1031,8,1.5600000000000001,1 +334,10310,1031,8,1.3,1 +335,10310,1031,3,1.3,1 +336,10311,1031,8,1.3,1 +337,10311,1031,8,1.4300000000000002,1 +338,10311,1031,8,1.5600000000000001,1 +339,10311,1031,8,1.3,1 +340,10311,1031,8,1.4300000000000002,1 +341,10311,1031,8,1.5600000000000001,1 +342,10311,1031,3,1.3,1 +343,10312,1031,8,1.3,1 +344,10312,1031,8,1.4300000000000002,1 +345,10312,1031,8,1.5600000000000001,1 +346,10312,1031,8,1.3,1 +347,10312,1031,8,1.4300000000000002,1 +348,10312,1031,3,1.3,1 +349,10313,1031,8,1.3,1 +350,10313,1031,8,1.4300000000000002,1 +351,10313,1031,8,1.5600000000000001,1 +352,10313,1031,8,1.3,1 +353,10313,1031,3,1.3,1 +354,10320,1032,8,1.3999999999999999,1 +355,10320,1032,8,1.54,1 +356,10320,1032,8,1.6799999999999999,1 +357,10320,1032,8,1.3999999999999999,1 +358,10320,1032,8,1.54,1 +359,10320,1032,8,1.6799999999999999,1 +360,10320,1032,3,1.3999999999999999,1 +361,10330,1033,7,1.5,1 +362,10330,1033,7,1.6500000000000001,1 +363,10330,1033,7,1.7999999999999998,1 +364,10330,1033,7,1.5,1 +365,10330,1033,7,1.6500000000000001,1 +366,10330,1033,3,1.5,1 +367,10331,1033,7,1.5,1 +368,10331,1033,7,1.6500000000000001,1 +369,10331,1033,7,1.7999999999999998,1 +370,10331,1033,7,1.5,1 +371,10331,1033,3,1.5,1 +372,10340,1034,8,1.6000000000000001,1 +373,10340,1034,8,1.7600000000000002,1 +374,10340,1034,8,1.9199999999999999,1 +375,10340,1034,8,1.6000000000000001,1 +376,10340,1034,3,1.6000000000000001,1 +377,10341,1034,8,1.6000000000000001,1 +378,10341,1034,8,1.7600000000000002,1 +379,10341,1034,8,1.9199999999999999,1 +380,10341,1034,3,1.6000000000000001,1 +381,10342,1034,8,1.6000000000000001,1 +382,10342,1034,8,1.7600000000000002,1 +383,10342,1034,3,1.6000000000000001,1 +384,10350,1035,3,1,1 +385,10351,1035,8,1,1 +386,10351,1035,8,1.1000000000000001,1 +387,10351,1035,3,1,1 +388,10352,1035,8,1,1 +389,10352,1035,3,1,1 +390,10353,1035,3,1,1 +391,10360,1036,8,1.1000000000000001,1 +392,10360,1036,8,1.2100000000000002,1 +393,10360,1036,3,1.1000000000000001,1 +394,10370,1037,8,1.2,1 +395,10370,1037,3,1.2,1 +396,10371,1037,3,1.2,1 +397,10380,1038,3,1.3,1 +398,10381,1038,3,1.3,1 +399,10382,1038,8,1.3,1 +400,10382,1038,8,1.4300000000000002,1 +401,10382,1038,8,1.5600000000000001,1 +402,10382,1038,8,1.3,1 +403,10382,1038,8,1.4300000000000002,1 +404,10382,1038,8,1.5600000000000001,1 +405,10382,1038,8,1.3,1 +406,10382,1038,8,1.4300000000000002,1 +407,10382,1038,3,1.3,1 +408,10390,1039,3,1.3999999999999999,1 +409,10391,1039,8,1.3999999999999999,1 +410,10391,1039,8,1.54,1 +411,10391,1039,8,1.6799999999999999,1 +412,10391,1039,8,1.3999999999999999,1 +413,10391,1039,8,1.54,1 +414,10391,1039,8,1.6799999999999999,1 +415,10391,1039,8,1.3999999999999999,1 +416,10391,1039,8,1.54,1 +417,10391,1039,3,1.3999999999999999,1 +418,10392,1039,8,1.3999999999999999,1 +419,10392,1039,8,1.54,1 +420,10392,1039,8,1.6799999999999999,1 +421,10392,1039,8,1.3999999999999999,1 +422,10392,1039,8,1.54,1 +423,10392,1039,8,1.6799999999999999,1 +424,10392,1039,8,1.3999999999999999,1 +425,10392,1039,3,1.3999999999999999,1 +426,10393,1039,8,1.3999999999999999,1 +427,10393,1039,8,1.54,1 +428,10393,1039,8,1.6799999999999999,1 +429,10393,1039,8,1.3999999999999999,1 +430,10393,1039,8,1.54,1 +431,10393,1039,8,1.6799999999999999,1 +432,10393,1039,3,1.3999999999999999,1 +433,10400,1040,8,1.5,1 +434,10400,1040,8,1.6500000000000001,1 +435,10400,1040,8,1.7999999999999998,1 +436,10400,1040,8,1.5,1 +437,10400,1040,8,1.6500000000000001,1 +438,10400,1040,8,1.7999999999999998,1 +439,10400,1040,8,1.5,1 +440,10400,1040,8,1.6500000000000001,1 +441,10400,1040,3,1.5,1 +442,10410,1041,8,1.6000000000000001,1 +443,10410,1041,8,1.7600000000000002,1 +444,10410,1041,8,1.9199999999999999,1 +445,10410,1041,8,1.6000000000000001,1 +446,10410,1041,8,1.7600000000000002,1 +447,10410,1041,8,1.9199999999999999,1 +448,10410,1041,8,1.6000000000000001,1 +449,10410,1041,3,1.6000000000000001,1 +450,10411,1041,8,1.6000000000000001,1 +451,10411,1041,8,1.7600000000000002,1 +452,10411,1041,8,1.9199999999999999,1 +453,10411,1041,8,1.6000000000000001,1 +454,10411,1041,8,1.7600000000000002,1 +455,10411,1041,8,1.9199999999999999,1 +456,10411,1041,3,1.6000000000000001,1 +457,10420,1042,7,1,1 +458,10420,1042,7,1.1000000000000001,1 +459,10420,1042,7,1.2,1 +460,10420,1042,7,1,1 +461,10420,1042,7,1.1000000000000001,1 +462,10420,1042,7,1.2,1 +463,10420,1042,3,1,1 +464,10421,1042,7,1,1 +465,10421,1042,7,1.1000000000000001,1 +466,10421,1042,7,1.2,1 +467,10421,1042,7,1,1 +468,10421,1042,7,1.1000000000000001,1 +469,10421,1042,3,1,1 +470,10422,1042,7,1,1 +471,10422,1042,7,1.1000000000000001,1 +472,10422,1042,7,1.2,1 +473,10422,1042,7,1,1 +474,10422,1042,3,1,1 +475,10430,1043,8,1.1000000000000001,1 +476,10430,1043,8,1.2100000000000002,1 +477,10430,1043,8,1.3200000000000001,1 +478,10430,1043,8,1.1000000000000001,1 +479,10430,1043,8,1.2100000000000002,1 +480,10430,1043,3,1.1000000000000001,1 +481,10431,1043,8,1.1000000000000001,1 +482,10431,1043,8,1.2100000000000002,1 +483,10431,1043,8,1.3200000000000001,1 +484,10431,1043,8,1.1000000000000001,1 +485,10431,1043,3,1.1000000000000001,1 +486,10432,1043,8,1.1000000000000001,1 +487,10432,1043,8,1.2100000000000002,1 +488,10432,1043,8,1.3200000000000001,1 +489,10432,1043,3,1.1000000000000001,1 +490,10433,1043,8,1.1000000000000001,1 +491,10433,1043,8,1.2100000000000002,1 +492,10433,1043,3,1.1000000000000001,1 +493,10440,1044,8,1.2,1 +494,10440,1044,8,1.3200000000000001,1 +495,10440,1044,8,1.4399999999999999,1 +496,10440,1044,8,1.2,1 +497,10440,1044,3,1.2,1 +498,10450,1045,8,1.3,1 +499,10450,1045,8,1.4300000000000002,1 +500,10450,1045,8,1.5600000000000001,1 +501,10450,1045,3,1.3,1 +502,10451,1045,8,1.3,1 +503,10451,1045,8,1.4300000000000002,1 +504,10451,1045,3,1.3,1 +505,10460,1046,3,1.3999999999999999,1 +506,10461,1046,8,1.3999999999999999,1 +507,10461,1046,3,1.3999999999999999,1 +508,10462,1046,3,1.3999999999999999,1 +509,10470,1047,8,1.5,1 +510,10470,1047,3,1.5,1 +511,10471,1047,3,1.5,1 +512,10472,1047,3,1.5,1 +513,10473,1047,8,1.5,1 +514,10473,1047,8,1.6500000000000001,1 +515,10473,1047,8,1.7999999999999998,1 +516,10473,1047,8,1.5,1 +517,10473,1047,8,1.6500000000000001,1 +518,10473,1047,8,1.7999999999999998,1 +519,10473,1047,8,1.5,1 +520,10473,1047,8,1.6500000000000001,1 +521,10473,1047,3,1.5,1 +522,10480,1048,3,1.6000000000000001,1 +523,10490,1049,3,1,1 +524,10491,1049,8,1,1 +525,10491,1049,8,1.1000000000000001,1 +526,10491,1049,8,1.2,1 +527,10491,1049,8,1,1 +528,10491,1049,8,1.1000000000000001,1 +529,10491,1049,8,1.2,1 +530,10491,1049,8,1,1 +531,10491,1049,8,1.1000000000000001,1 +532,10491,1049,3,1,1 +533,10500,1050,8,1.1000000000000001,1 +534,10500,1050,8,1.2100000000000002,1 +535,10500,1050,8,1.3200000000000001,1 +536,10500,1050,8,1.1000000000000001,1 +537,10500,1050,8,1.2100000000000002,1 +538,10500,1050,8,1.3200000000000001,1 +539,10500,1050,8,1.1000000000000001,1 +540,10500,1050,8,1.2100000000000002,1 +541,10500,1050,3,1.1000000000000001,1 +542,10501,1050,8,1.1000000000000001,1 +543,10501,1050,8,1.2100000000000002,1 +544,10501,1050,8,1.3200000000000001,1 +545,10501,1050,8,1.1000000000000001,1 +546,10501,1050,8,1.2100000000000002,1 +547,10501,1050,8,1.3200000000000001,1 +548,10501,1050,8,1.1000000000000001,1 +549,10501,1050,3,1.1000000000000001,1 +550,10502,1050,8,1.1000000000000001,1 +551,10502,1050,8,1.2100000000000002,1 +552,10502,1050,8,1.3200000000000001,1 +553,10502,1050,8,1.1000000000000001,1 +554,10502,1050,8,1.2100000000000002,1 +555,10502,1050,8,1.3200000000000001,1 +556,10502,1050,3,1.1000000000000001,1 +557,10510,1051,7,1.2,1 +558,10510,1051,7,1.3200000000000001,1 +559,10510,1051,7,1.4399999999999999,1 +560,10510,1051,7,1.2,1 +561,10510,1051,7,1.3200000000000001,1 +562,10510,1051,7,1.4399999999999999,1 +563,10510,1051,7,1.2,1 +564,10510,1051,3,1.2,1 +565,10511,1051,7,1.2,1 +566,10511,1051,7,1.3200000000000001,1 +567,10511,1051,7,1.4399999999999999,1 +568,10511,1051,7,1.2,1 +569,10511,1051,7,1.3200000000000001,1 +570,10511,1051,7,1.4399999999999999,1 +571,10511,1051,3,1.2,1 +572,10512,1051,7,1.2,1 +573,10512,1051,7,1.3200000000000001,1 +574,10512,1051,7,1.4399999999999999,1 +575,10512,1051,7,1.2,1 +576,10512,1051,7,1.3200000000000001,1 +577,10512,1051,3,1.2,1 +578,10513,1051,7,1.2,1 +579,10513,1051,7,1.3200000000000001,1 +580,10513,1051,7,1.4399999999999999,1 +581,10513,1051,7,1.2,1 +582,10513,1051,3,1.2,1 +583,10520,1052,8,1.3,1 +584,10520,1052,8,1.4300000000000002,1 +585,10520,1052,8,1.5600000000000001,1 +586,10520,1052,8,1.3,1 +587,10520,1052,8,1.4300000000000002,1 +588,10520,1052,8,1.5600000000000001,1 +589,10520,1052,3,1.3,1 +590,10530,1053,8,1.3999999999999999,1 +591,10530,1053,8,1.54,1 +592,10530,1053,8,1.6799999999999999,1 +593,10530,1053,8,1.3999999999999999,1 +594,10530,1053,8,1.54,1 +595,10530,1053,3,1.3999999999999999,1 +596,10531,1053,8,1.3999999999999999,1 +597,10531,1053,8,1.54,1 +598,10531,1053,8,1.6799999999999999,1 +599,10531,1053,8,1.3999999999999999,1 +600,10531,1053,3,1.3999999999999999,1 +601,10540,1054,8,1.5,1 +602,10540,1054,8,1.6500000000000001,1 +603,10540,1054,8,1.7999999999999998,1 +604,10540,1054,8,1.5,1 +605,10540,1054,3,1.5,1 +606,10541,1054,8,1.5,1 +607,10541,1054,8,1.6500000000000001,1 +608,10541,1054,8,1.7999999999999998,1 +609,10541,1054,3,1.5,1 +610,10542,1054,8,1.5,1 +611,10542,1054,8,1.6500000000000001,1 +612,10542,1054,3,1.5,1 +613,10550,1055,8,1.6000000000000001,1 +614,10550,1055,8,1.7600000000000002,1 +615,10550,1055,8,1.9199999999999999,1 +616,10550,1055,3,1.6000000000000001,1 +617,10551,1055,8,1.6000000000000001,1 +618,10551,1055,8,1.7600000000000002,1 +619,10551,1055,3,1.6000000000000001,1 +620,10552,1055,8,1.6000000000000001,1 +621,10552,1055,3,1.6000000000000001,1 +622,10553,1055,3,1.6000000000000001,1 +623,10560,1056,8,1,1 +624,10560,1056,8,1.1000000000000001,1 +625,10560,1056,3,1,1 +626,10570,1057,3,1.1000000000000001,1 +627,10571,1057,3,1.1000000000000001,1 +628,10580,1058,3,1.2,1 +629,10581,1058,3,1.2,1 +630,10582,1058,8,1.2,1 +631,10582,1058,8,1.3200000000000001,1 +632,10582,1058,8,1.4399999999999999,1 +633,10582,1058,8,1.2,1 +634,10582,1058,8,1.3200000000000001,1 +635,10582,1058,8,1.4399999999999999,1 +636,10582,1058,8,1.2,1 +637,10582,1058,8,1.3200000000000001,1 +638,10582,1058,3,1.2,1 +639,10590,1059,3,1.3,1 +640,10591,1059,8,1.3,1 +641,10591,1059,8,1.4300000000000002,1 +642,10591,1059,8,1.5600000000000001,1 +643,10591,1059,8,1.3,1 +644,10591,1059,8,1.4300000000000002,1 +645,10591,1059,8,1.5600000000000001,1 +646,10591,1059,8,1.3,1 +647,10591,1059,8,1.4300000000000002,1 +648,10591,1059,3,1.3,1 +649,10592,1059,3,1.3,1 +650,10593,1059,8,1.3,1 +651,10593,1059,8,1.4300000000000002,1 +652,10593,1059,8,1.5600000000000001,1 +653,10593,1059,8,1.3,1 +654,10593,1059,8,1.4300000000000002,1 +655,10593,1059,8,1.5600000000000001,1 +656,10593,1059,3,1.3,1 +657,10600,1060,7,1.3999999999999999,1 +658,10600,1060,7,1.54,1 +659,10600,1060,7,1.6799999999999999,1 +660,10600,1060,7,1.3999999999999999,1 +661,10600,1060,7,1.54,1 +662,10600,1060,7,1.6799999999999999,1 +663,10600,1060,7,1.3999999999999999,1 +664,10600,1060,7,1.54,1 +665,10600,1060,3,1.3999999999999999,1 +666,10610,1061,8,1.5,1 +667,10610,1061,8,1.6500000000000001,1 +668,10610,1061,8,1.7999999999999998,1 +669,10610,1061,8,1.5,1 +670,10610,1061,8,1.6500000000000001,1 +671,10610,1061,8,1.7999999999999998,1 +672,10610,1061,8,1.5,1 +673,10610,1061,3,1.5,1 +674,10611,1061,8,1.5,1 +675,10611,1061,8,1.6500000000000001,1 +676,10611,1061,8,1.7999999999999998,1 +677,10611,1061,8,1.5,1 +678,10611,1061,8,1.6500000000000001,1 +679,10611,1061,8,1.7999999999999998,1 +680,10611,1061,3,1.5,1 +681,10620,1062,8,1.6000000000000001,1 +682,10620,1062,8,1.7600000000000002,1 +683,10620,1062,8,1.9199999999999999,1 +684,10620,1062,8,1.6000000000000001,1 +685,10620,1062,8,1.7600000000000002,1 +686,10620,1062,8,1.9199999999999999,1 +687,10620,1062,3,1.6000000000000001,1 +688,10621,1062,8,1.6000000000000001,1 +689,10621,1062,8,1.7600000000000002,1 +690,10621,1062,8,1.9199999999999999,1 +691,10621,1062,8,1.6000000000000001,1 +692,10621,1062,8,1.7600000000000002,1 +693,10621,1062,3,1.6000000000000001,1 +694,10622,1062,8,1.6000000000000001,1 +695,10622,1062,8,1.7600000000000002,1 +696,10622,1062,8,1.9199999999999999,1 +697,10622,1062,8,1.6000000000000001,1 +698,10622,1062,3,1.6000000000000001,1 +699,10630,1063,8,1,1 +700,10630,1063,8,1.1000000000000001,1 +701,10630,1063,8,1.2,1 +702,10630,1063,8,1,1 +703,10630,1063,8,1.1000000000000001,1 +704,10630,1063,3,1,1 +705,10631,1063,8,1,1 +706,10631,1063,8,1.1000000000000001,1 +707,10631,1063,8,1.2,1 +708,10631,1063,8,1,1 +709,10631,1063,3,1,1 +710,10632,1063,8,1,1 +711,10632,1063,8,1.1000000000000001,1 +712,10632,1063,8,1.2,1 +713,10632,1063,3,1,1 +714,10633,1063,8,1,1 +715,10633,1063,8,1.1000000000000001,1 +716,10633,1063,3,1,1 diff --git a/tools/build_uk_e6_support_bounds.py b/tools/build_uk_e6_support_bounds.py index 87b93ecbf..fcff93e7e 100644 --- a/tools/build_uk_e6_support_bounds.py +++ b/tools/build_uk_e6_support_bounds.py @@ -30,6 +30,12 @@ from microcosm.build.uk_runtime.lcfs_consumption import ( donor_realized_ranges as lcfs_ranges, ) +from microcosm.build.uk_runtime.nts_bus_travel import ( + CLEAN_NTS_TRAVEL_TABLES_KIND, + NTSColumns, + clean_nts_travel_tables, + nts_support_ranges, +) REPO_ROOT = Path(__file__).resolve().parents[1] UK_PACKAGE = REPO_ROOT / "packages/microcosm-build/src/microcosm/build/uk" @@ -99,14 +105,60 @@ def build_etb_services_support_bounds(etb_tab: Path) -> dict[str, object]: ) +def build_nts_support_bounds( + household_tab: Path, individual_tab: Path, trip_tab: Path +) -> dict[str, object]: + """Bounds of the nts_bus_travel person outputs from the pinned NTS tabs (#930).""" + + stage = _committed_stage("nts_bus_travel") + derive = next( + dict(op.parameters) + for op in stage.operations + if op.kind == CLEAN_NTS_TRAVEL_TABLES_KIND + ) + columns = NTSColumns.from_parameters(derive) + cars_clip = tuple(int(v) for v in derive.get("cars_clip", (0, 5))) + donor = clean_nts_travel_tables( + pd.read_csv(household_tab, sep="\t", low_memory=False), + pd.read_csv(individual_tab, sep="\t", low_memory=False), + pd.read_csv(trip_tab, sep="\t", low_memory=False), + columns=columns, + cars_clip=(cars_clip[0], cars_clip[1]), + ) + return _payload( + source={ + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "household_tab_sha256": _sha256(household_tab), + "individual_tab_sha256": _sha256(individual_tab), + "trip_tab_sha256": _sha256(trip_tab), + }, + bounds=nts_support_ranges(donor.person), + label="NTS bus travel", + ) + + def main(argv: list[str] | None = None) -> int: parser = argparse.ArgumentParser() parser.add_argument("--lcfs-hh-tab", type=Path) parser.add_argument("--lcfs-person-tab", type=Path) parser.add_argument("--etb-tab", type=Path) + parser.add_argument("--nts-household-tab", type=Path) + parser.add_argument("--nts-individual-tab", type=Path) + parser.add_argument("--nts-trip-tab", type=Path) parser.add_argument("--check", action="store_true") args = parser.parse_args(argv) jobs: list[tuple[Path, dict[str, object]]] = [] + nts = (args.nts_household_tab, args.nts_individual_tab, args.nts_trip_tab) + if any(nts): + if not all(nts): + raise SystemExit("NTS support bounds require all three NTS tabs.") + jobs.append( + ( + UK_PACKAGE / "nts_bus_travel_support_bounds.json", + build_nts_support_bounds(*nts), + ) + ) if args.lcfs_hh_tab or args.lcfs_person_tab: if not args.lcfs_hh_tab or not args.lcfs_person_tab: raise SystemExit("LCFS support bounds require both LCFS tabs.") diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index a4baae73e..02805bd54 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -674,11 +674,13 @@ def _lcfs_donors() -> tuple[pd.DataFrame, pd.DataFrame]: def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: """Synthetic NTS Household, Individual and Trip tables (2022-2024). - Column names and codes follow the stage's declared codebook: nine English - GOR codes, the three income bands, W2 household weights, banded ages, - the interview frequency band (1 = 3+ a week ... 7 = less than yearly or - never) and diary trips whose main mode is bus in London (7) or other - local bus (8), each with the trip weight and the short-walk multiplier. + Column names and codes follow the stage's declared codebook (the SN 5340 + 19th-edition lookup tables): nine English GOR codes, the three income + bands, W2 household weights, the 21 Age_B01ID bands, the ten-code + OrdBus2Freq_B01ID frequency question (1 = at least once a day ... 10 = + never; -9 = not applicable, a declared non-user) and diary trips whose + main mode is bus in London (7) or other local bus (8), each with the W5 + trip weight (which carries W2) and the short-walk multiplier. """ households = _DONOR_ROWS @@ -704,21 +706,28 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: { "IndividualID": index, "HouseholdID": int(household_id), - "Age_B01ID": 1 + (index % 10), + "Age_B01ID": 1 + (index % 21), "Sex_B01ID": 1 + (index % 2), - # Frequent riders in the low-income, car-free households; - # the never band elsewhere, with every band populated. - "LocalBusFreq_B01ID": 1 + (index % 7), + # Every frequency code populated, the not-applicable code + # (-9, a declared non-user) on one person in eleven. + "OrdBus2Freq_B01ID": ( + -9 + if index % 11 == 10 + else 1 + (int(household_id) + member) % 10 + ), } ) individual = pd.DataFrame(person_rows) + w2_by_household = dict(zip(household["HouseholdID"], household["W2"], strict=True)) trip_rows = [] trip_id = 1 for _, person in individual.iterrows(): - band = int(person["LocalBusFreq_B01ID"]) - # More trips for the frequent bands, none for the never band. - trips = max(0, 7 - band) if band < 7 else 0 + code = int(person["OrdBus2Freq_B01ID"]) + # More trips for the frequent codes, none for the never / not-applicable + # codes (the NTS0313 bands fold codes 1-3 and 9-10 together). + trips = max(0, 9 - code) if 0 < code < 9 else 0 london = (int(person["HouseholdID"]) - 1000) % 9 == 6 + w2 = float(w2_by_household[int(person["HouseholdID"])]) for t in range(trips): trip_rows.append( { @@ -726,7 +735,7 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: "IndividualID": int(person["IndividualID"]), "HouseholdID": int(person["HouseholdID"]), "MainMode_B04ID": 7 if london else 8, - "W5xHH": 1.0 + (t % 3) / 10.0, + "W5": w2 * (1.0 + (t % 3) / 10.0), "JJXSC": 1.0, } ) @@ -738,7 +747,7 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: "IndividualID": int(person["IndividualID"]), "HouseholdID": int(person["HouseholdID"]), "MainMode_B04ID": 3, - "W5xHH": 1.0, + "W5": w2, "JJXSC": 1.0, } ) From 3945aa3ebdaa61af918e44034aef8bca0d33c48b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Tue, 22 Sep 2026 18:14:14 +0100 Subject: [PATCH 08/19] Record the licensed measurement: the pinned tabs and verified codebook, spine-t against its main twin, and the national calibration with the stretch anatomy (#930 C11) Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 187 +++++++++++++++++-- 1 file changed, 175 insertions(+), 12 deletions(-) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index a8f56b2fb..6122148bb 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -166,15 +166,178 @@ inputs); the gate battery (53 gates, four new); the gate-battery and certificati re-pinned in `microcosm-data` after every `gates.json` edit; `tools/ci_test_groups.py --verify` ok. Export surface gains `household.household_local_bus_trips`. -## Part E — licensed measurement (pending María's NTS SN 5340 download) - -Not run. In order once the tabs are at `data/ukds/nts_2002_24/`: pin the three artifacts in -`sources.yaml`; spine-t with the #791 twin recipe (`build_791.sh`, the three tabs added) under -`data/ukds/acceptance/930-nts-bus/spine-t/`; the stage gates and their receipts (band shares vs -NTS0313, trips per person by series, quintile and age vs NTS0705a/NTS0303/NTS0601, vehicle -shares vs NTS0205, the eligible trip share beside C/B, frame-implied boardings vs BUS01, the -design-weight fares by target cell against the #904 targets without a rake, the ONS 07.3.2 upper -bound, the support-per-journey reading); the twin diff against spine-s5 under its expectation -(only the new cells and `bus_fare_spending` outside Wales may move); the E6 support bounds for -the new stage; the national calibration round (after #937 or with the round-5 scratch -register) and the Part C anatomy per bus row. +## Part E — the tabs land: pins and the verified codebook (C10, commit `2b7368cc`, 2026-09-22) + +María placed SN 5340 (19th edition, November 2025; End User Licence) under +`data/ukds/nts_2002_24/tab/`. The branch was rebased onto main `87e0ac07` first (clean: main had +moved only the calibration attempt-id minting and the data contract since `ce76b358`). The three +tabs are pinned by size and digest and verified at runtime through the FRS spine's pinned-tab reader: + +- `household_eul_2002-2024.tab` 117,993,975 bytes, sha256 `b70252b6…` +- `individual_eul_2002-2024.tab` 270,677,548 bytes, sha256 `e8b56849…` +- `trip_eul_2002-2024.tab` 1,055,711,332 bytes, sha256 `878b61c9…` + +The declared codebook was checked against the deposited lookup tables (variables and response +levels) and the data extract user guide. Three corrections, each declared, receipted and tested: + +- The frequency-of-use question is `OrdBus2Freq_B01ID` ("How frequently use local buses", asked + since 2019; `OrdBusFreq_B01ID` ended in 2018; the declared `LocalBusFreq_B01ID` never existed). + Its ten codes fold onto the seven NTS0313 bands (1–3 → three or more times a week, 4 → once or + twice a week, 5, 6, 7, 8 one band each, 9 and 10 → less than once a year or never). Code -9 + (not applicable, proxy responses; 2,122 persons in 2022–24, none of them under-5s) is declared a + non-user because the published NTS0313 shares reproduce only with those persons in the base: + the 2024 at-least-yearly share is 0.526 without them, 0.505 with them, published 0.505 (and + 0.556 vs 0.500 for the 60-and-over series, published 0.500). Code -8 (no answer) is dropped and + receipted (41 persons in the declared years). +- `Age_B01ID` carries 21 bands (under 1 to 85+). The codebook now maps each code to its lower age + and the declared edges (0, 5, 11, 17, 21, 30, 40, 50, 60, 70) band donor and recipient alike; + every NTS band lies inside one declared band. The earlier one-to-one assumption (code minus one + as the ordinal) would have put a 5-to-10-year-old in the fourth declared band while the frame + put the same child in the second, misaligning the QRF's first predictor. +- The trip weight is `W5`, which already carries the diary household weight W2 (the user guide's + trips per person per year is 52.14 × Σ(JJXSC × W5) / Σ W2 on the diary sample; W5xHH, the + earlier declaration, is the within-household factor only, and W5 / (W2 × W5xHH) has median + 0.99 and a 1st–99th percentile range of 0.90–1.24 on the 2022–24 bus trips). Each person's + counted trips are divided by W2 before the W2-weighted mean (`trip_weight_basis: + household_and_trip`, a declared and receipted basis). Interview-only households (W2 of zero; + 3,074 of 20,564 in 2022–24) leave the donor, as the guide prescribes for trip measures. + +Also verified unchanged: `HHoldGOR_B02ID` 1–9 are the English regions (10 Wales and 11 Scotland +occur only before 2013), `HHIncome2002_B02ID` 1–3 at £25,000 and £50,000 (-8 dropped, 33 +households), `Sex_B01ID` 2 = female, `MainMode_B04ID` 7 = bus in London and 8 = other local bus, +`NumCarVan` the raw count (clipped 0–5), `HHoldNumPeople`, `JJXSC` ∈ {0, 1, 7}. + +The E6 bounds `uk/nts_bus_travel_support_bounds.json` (band 0–6, each trip column 0–2,000 after +outward rounding, from the pinned tabs through the stage's own cleaning) join the terminal +`uk_support` gate; the H2 fixture's synthetic tabs follow the verified codebook (oracle identity +on this machine `6c5dffbc…`); coverage manifest and digests regenerated. + +## Part F — spine-t and its twin (2026-09-22) + +Twin recipe `data/ukds/acceptance/930-nts-bus/build_930.sh` (the #791 recipe on the post-#939 tool: +no `--cgt-ods`, `--no-staging`). Control spine-u from main `87e0ac07` in a scratch worktree with its +own venv (uk extra), 299 s, 20 of 20 stage gates, sha256 `16814f8b…`. Candidate spine-t from +`2b7368cc` with the three tabs, 369 s, engine 2.98.0, 24 of 24 stage gates (the four #930 gates +among them), sha256 `bbbf40e4…`. + +Stage receipts on spine-t (design weights, the FRS 2024-25 sample of 34,966 persons in 16,288 +households before the CGT incidence clone): + +- Donor: 17,457 diary households, 39,047 persons over 2022–24 (weighted 41,280), region + unmapped 0, income missing 33, frequency -8 dropped 41, age unmapped 0. Donor trips per + person 13.73 (bus in London) and 26.05 (other local bus) against the published 2024 rates + 13.12 and 28.07 (the pooled donor years straddle the post-pandemic recovery). +- Band draw: regime-gated QRF, zero-inflated positive regime, 14 predictors (age band, sex, cars, + household size, income band, nine region indicators), identity-keyed uniforms; donor band + shares reproduce the NTS0313 shape (non-user 0.511, three-or-more-a-week 0.127). +- Incidence on the frame: person user share 0.5047 against NTS0313 2024 0.5049; 60-and-over user + share 0.5010 against NTS0621 0.5004; household user share 0.723. `bus_travel_facts` passes at + a 0.05 tolerance with a deviation of 0.0002. +- Trip rates on the frame: 12.42 bus-in-London trips per person (−5.3 % on NTS0303's 13.12) and + 31.11 other-local-bus trips (+10.8 % on 28.07), inside the 15 % fence; by age the rest-of-England + series peaks at 17–20 (70.7 trips) and 70-and-over (37.9), the London series at 21–29 (20.5). +- Band means (diary, per band and residence group): London residents in the top band average + 206 bus-in-London trips a year, the once-or-twice-a-week band 62, non-users 13; rest-of-England + top band 2.0 London trips; no cell fell back to the all-England mean. +- Eligibility (statutory age rule): 10,874 eligible persons (England outside London 5,739 of + 22,466; London 1,311 of 2,860; Scotland 1,929 of 3,325; Wales 1,007 of 2,370; Northern Ireland + 888 of 3,945). The donor's eligible share of trips is 0.442 for the London series and 0.168 for + other local bus (age-band lower bounds). +- Vehicle shares (frame vs NTS0205 2024, receipt line): no car 0.236 vs 0.218, one car 0.463 vs + 0.442, two-plus 0.301 vs 0.340. A `was_wealth` finding, as the plan said; not fenced here. +- Support clip: 0 rows clipped on the four columns (donor maxima 1,690 and 1,818 trips). + +Pricing on spine-t (lcfs `bus_pricing`, gate `uk_stage_lcfs_consumption_bus_pricing` passing at +1e-9): 32,596 persons priced, 9,867 eligible persons zero-priced, 15,112 households priced, 1,176 +Wales households keep the raw draw. Design-weight fares against the bound receipts, the #930 +acceptance line: + +- England outside London: frame £2,316m against BUS05ai £2,070m, frame / R 1.119; frame-implied + boardings over BUS01 1.018; frame eligible trip share 0.209 beside the publisher's concessionary + boarding share 0.281. +- London series: £1,215m against £1,347m, 0.902; boardings ratio 1.101; eligible share 0.405 + beside 0.273. +- Scotland: £558m against £391m, 1.428; boardings ratio 1.534; eligible share 0.581 beside 0.550. +- Northern Ireland: £264m against £150m, 1.757; boardings ratio 1.938; eligible share 0.213 + beside 0.132. + +Reading: the two England cells sit inside the 25 % fence without any rake (the algebra's two +factors are 1.02 × 1.10 for England outside London and 1.10 × 0.82 for London: the composition +check is near one, the concession check says the frame's London eligible share is above the +publisher's boarding share). The two devolved cells are outside it, and the boardings ratio says +why: their persons are predicted on a declared proxy region (`region_remap`: Scotland and Northern +Ireland → North East, a high-bus region), so the frame gives them 1.5× and 1.9× the boardings the +publisher counts. That is a translation choice, not a level the stage set; the receipts carry it +for María's ruling (a different proxy region, or the devolved trip rates scaled to the published +boardings, are the candidate fixes). The weighted fares total moves from £2,783m (the #890 raked +level on the same frame) to £4,354m before calibration, of which £2,316m + £1,215m is England. + +Support-per-journey diagnostic (ETB, recorded, not applied): England outside London value-side +£1,807m against the raked £1,895m (0.953); London £1,308m against £1,130m (1.158; the frame's +eligible boarding share 0.410 against the publisher's 0.273 drives it). The `fact_rake` gate +passes on all five cells at 1e-6. + +Twin diff (`twin_diff_930.sh`, expectation `spine-t-payload-expectation.json`): compare and +classify report nine observed differences, seven expected (the five new person columns at +positions 99–103 of 104, the household sum at position 40 of 75, and `bus_fare_spending` values), +two unexpected, both the `column_order` structural surface the classifier cannot declare +expected; adjudicated as the #791 twin was, by the position-wise check that every shared column +keeps its order (person 99 shared, household 74, benunit 22) and no shared column other than +`bus_fare_spending` moves. `bus_fare_spending`: 3,806 Wales rows byte-equal, 42,540 of 49,040 +other rows changed (the remainder are zero both sides). Weights, indices, row counts, root +attributes and every other column byte-equal. + +## Part G — national calibration on spine-t and the stretch anatomy (2026-09-22) + +`calibrate_930.sh`: the rowwise driver's national release role (`tools/build_uk_rowwise_candidate.py +--release-role national`, the seam that replaced the retired calibration runner under #823; doctrine +solve, no flags: 1,500 epochs, `family_equal`, learning rate 0.02, seed 0), input spine-t sha256 +`bbbf40e4…`, the branch's own Chronicle artifact `7846605` (facts `8dc4336d…`, manifest +`0ff28c71…`), staging local-only, release id `uk-930-spine-t-calibration`, code `2b7368cc` clean. +473 s. Outputs under `data/ukds/acceptance/930-nts-bus/calibration-t/`: `microcosm_uk_2024_25.h5` +sha256 `e6919c04…`, `calibration_diagnostics.json` `e24078e2…`, the frozen +`national_target_registry.json`, the terminal gate report and the Part C sidecars +(`target_support_matrix.npz`, `target_support_vectors.npz`, `target_support_manifest.json`). + +- Terminal battery: all six gates pass, nothing blocked, `release_candidate: false` (the national + role never signs shippability). The H5 was written. +- Fit: 638 compiled targets on 52,846 records (all carrying weight); loss 0.3065 → 0.01036; + 96.55 % of rows within 10 %; ESS 9,231; realised max weight ratio 10.0 (the cap); top-1 % + weight share 0.162. The v20 twin on main `ce76b358` (same register, 638 rows): loss 0.3009 → + 0.01041, 96.39 % within 10 %, ESS 9,305, top-1 % 0.163. The structural change costs nothing in + fit: loss and the within-10 % share move a hair in #930's favour, ESS 0.8 % against. The eight + rows still beyond 10 % after the solve are the same eight on both (income tax −13 %, VAT +18 %, + CGT liability +10 %, child benefit +19 %, council tax −12 %, ESA −10 %, the two HMRC + self-employment bands +25 % and +18 %): none is a bus row, none moved with #930. +- Bus rows, design weights → final (the #930 acceptance reading, now a measurement instead of + the rake's tautology): England fare receipts (£3,612m, BUS0415-aligned to 2025) −10.9 % → 0.0 % + (v20, raked at base year then uprated: −6.1 %); London fare receipts (£1,347m) −21.6 % → +0.1 % + (v20 −2.6 %); Scotland passenger revenue (£391m) +27.8 % → −0.1 % (v20 −1.7 %); Northern + Ireland passenger receipts (£150m) +69.6 % → 0.0 % (v20 −4.0 %). Net support rows (England + +4.7 %, London +3.8 %, Scotland +1.3 %, Wales +3.8 %) are unchanged from v20, as the ETB rake + is kept. The two England fare rows sit inside the 25 % fence without a rake; the two devolved + rows do not, for the proxy-region reason Part F gives. +- Stretch anatomy (`tools/diagnose_uk_target_support.py`, thresholds 3× and 5×): the England + fare row's final mass on households stretched beyond 3× their design weight is 47.6 % against + the frame-wide 46.6 %, beyond 5× 36.2 % against 36.4 %, on 25,682 carriers with a top-1 carrier + share of 0.6 % and a median weight ratio of 0.46. The row is carried by the frame at large, not + by a stretched tail: this is the #890 acceptance line, measured for the first time, and it + passes. London fares: 55.2 % beyond 3× (46.6 %), 41.6 % beyond 5× (36.4 %), 2,875 carriers, + top-1 1.5 %. Scotland (13.5 % beyond 3×) and Northern Ireland (12.6 %) sit on down-weighted + carriers (median ratio ~0.5) because their design-weight estimates were above target. The + frame-wide 46.6 % beyond 3× is a property of this calibration campaign (the 10× cap binds), not + of #930. +- Score against the incumbent: not run. The in-tree `score_uk_national_candidate.py` refuses + the incumbent `enhanced_frs_2024_25.h5` (`e433e532…`) at the frame bundle's global-column rule + (`region`, `country`, `esa_contrib` on both person and household), and the evaluation repo's + `score_uk_pass2.py` (the v22 recipe) has drifted from this tree's scorer signature + (`band_edge_registry`). The rule-1 score belongs to the #823 assessment lane, which carries + that machinery; #930's acceptance is the fit, the bus rows and the anatomy above. + +Rulings this measurement puts to María: (1) the devolved proxy: Scotland and Northern Ireland +persons are predicted on North East's bus profile and price to 1.43× and 1.76× their receipts at +design weights (the calibration closes them, at the cost the anatomy shows is modest); the +alternatives are a different declared proxy region, or scaling the devolved series' trips to the +published boardings ratio; (2) whether the ETB support rake now retires in favour of the +support-per-journey value side (0.95 and 1.16 of the raked levels); (3) the vehicle-share gap +(frame two-plus-car households 0.301 against NTS0205's 0.340) as a `was_wealth` follow-up. From c73bded9744eb7d4682f36e9c7e75566a29de2b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 10:08:55 +0100 Subject: [PATCH 09/19] Retire the ETB bus-support rake: price bus support from the frame's journeys at the published support per boarding (#930 C12) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit María's ruling of 2026-09-23: raking retires with the imputation. The ETB stage no longer rakes bus_subsidy_spending to the published net support per area; a declared price_bus_support step sets each household's support from its persons' boardings (the nts_bus_travel trips times the fare pricing's boardings per resident trip) at the published support per boarding: the concessionary travel reimbursement per concessionary boarding for eligible persons plus the rest of the net support per boarding for every boarding, 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, as Wales fares do; the support clip no longer exempts the column. The published totals stay bound as calibration targets and now measure the priced quantity instead of a level the stage set. The rake_to_vendored_facts operation kind, uk_runtime/fact_raking.py and the fact_rake stage-health check leave with their last consumer; the uk_stage_etb_services_support_pricing gate recomputes every area's components and per-boarding rates from the vendored rows. The register's two resources name the pricing module; fixture, coverage manifest and digests regenerated. Co-Authored-By: Claude Fable 5.1 --- ...us-support-per-journey-diagnostic.added.md | 1 - .../930-bus-support-rake-retired.changed.md | 1 + .../src/microcosm/build/source_manifest.py | 3 +- .../spec_engine/schema/sources.schema.json | 136 +---- .../build/uk/devolved_bus_finance.json | 3 +- .../microcosm/build/uk/dft_bus_journeys.json | 2 +- .../src/microcosm/build/uk/gates.json | 15 +- .../uk/ledger_fact_vendor_selections.json | 5 +- .../src/microcosm/build/uk/source_stages.json | 187 +++---- .../src/microcosm/build/uk/spec/sources.yaml | 132 ++--- .../build/uk_runtime/battery_bindings.py | 3 - .../uk_runtime/bus_support_per_journey.py | 195 ------- .../build/uk_runtime/bus_support_pricing.py | 267 ++++++++++ .../build/uk_runtime/calibration_run.py | 2 +- .../build/uk_runtime/etb_services.py | 108 ++-- .../microcosm/build/uk_runtime/fact_raking.py | 492 ------------------ .../build/uk_runtime/stage_health.py | 159 +++--- .../tests/test_country_spec.py | 4 +- .../tests/test_uk_bus_support_per_journey.py | 193 ------- .../tests/test_uk_bus_support_pricing.py | 219 ++++++++ .../tests/test_uk_fact_raking.py | 374 ------------- .../tests/test_uk_source_stages.py | 3 +- .../tests/test_uk_stage_health.py | 121 ++--- .../src/microcosm/data/contract.py | 6 +- .../microcosm-data/tests/test_contract.py | 4 +- .../parity/uk_spine/sources/fixture.json | 185 +++---- 26 files changed, 878 insertions(+), 1942 deletions(-) delete mode 100644 changelog.d/930-bus-support-per-journey-diagnostic.added.md create mode 100644 changelog.d/930-bus-support-rake-retired.changed.md delete mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_pricing.py delete mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/fact_raking.py delete mode 100644 packages/microcosm-build/tests/test_uk_bus_support_per_journey.py create mode 100644 packages/microcosm-build/tests/test_uk_bus_support_pricing.py delete mode 100644 packages/microcosm-build/tests/test_uk_fact_raking.py diff --git a/changelog.d/930-bus-support-per-journey-diagnostic.added.md b/changelog.d/930-bus-support-per-journey-diagnostic.added.md deleted file mode 100644 index e12108a42..000000000 --- a/changelog.d/930-bus-support-per-journey-diagnostic.added.md +++ /dev/null @@ -1 +0,0 @@ -The ETB `bus_subsidy_spending` rake to the published net support (kept, per the #930 plan's default) is now fenced at stage time and measured against a value-side alternative (microcosm#930 C7, the #890 support-side leftover). A `fact_rake` stage-health check (`uk_stage_etb_services_support_rake`, a population fact check) recomputes every declared cell's published value from the vendored rows through the stage's own declaration, requires the receipt's cells to equal it and each cell's design-weighted total after the rake to equal its published value (the Northern Ireland cell jointly over bus and rail), and fails closed on a skipped cell; the #890 rake had no fence. A declared `record_support_per_journey` step (`uk_runtime/bus_support_per_journey.py`) records, per residence area where DfT publishes the components (London, England outside London), what pricing support from the frame's journeys would give: the BUS05 concessionary travel reimbursement per concessionary boarding times the frame's eligible boardings plus the rest of the net support per boarding times every boarding, with boardings the `nts_bus_travel` trips times the fare pricing's boardings per resident trip, beside the raked column's design-weighted total. It is a receipt (`support_per_journey`, `applied: false`), never a value: retiring the support rake is María's ruling with those numbers in hand. `dft_bus_journeys.json` names its two new consumers. diff --git a/changelog.d/930-bus-support-rake-retired.changed.md b/changelog.d/930-bus-support-rake-retired.changed.md new file mode 100644 index 000000000..0e15191a6 --- /dev/null +++ b/changelog.d/930-bus-support-rake-retired.changed.md @@ -0,0 +1 @@ +The ETB `bus_subsidy_spending` rake to the published net support is retired (microcosm#930; María's ruling of 2026-09-23 that raking retires with the imputation). A declared `price_bus_support` step (`uk_runtime/bus_support_pricing.py`) sets each household's bus support from the frame's journeys the way fares now are: 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, 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, as Wales fares do. The support clip no longer exempts the column; the published totals stay bound as calibration targets and now measure the priced quantity. The `rake_to_vendored_facts` operation kind, `uk_runtime/fact_raking.py` and the `fact_rake` stage-health check leave with their last consumer; `uk_stage_etb_services_support_pricing` (`bus_support_pricing`, a population fact check) recomputes every area's components and per-boarding rates from the vendored rows. `dft_bus_journeys.json` and `devolved_bus_finance.json` name the new consumer. diff --git a/packages/microcosm-build/src/microcosm/build/source_manifest.py b/packages/microcosm-build/src/microcosm/build/source_manifest.py index dec5dbcb2..fb82fe549 100644 --- a/packages/microcosm-build/src/microcosm/build/source_manifest.py +++ b/packages/microcosm-build/src/microcosm/build/source_manifest.py @@ -135,8 +135,7 @@ "pair_clone_households_to_originals", "price_domestic_energy", "price_bus_journeys", - "record_support_per_journey", - "rake_to_vendored_facts", + "price_bus_support", "map_columns", "map_coded_amounts", "map_uniform_to_banded_rate", 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 d7401a75a..178837ff9 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 @@ -8591,133 +8591,6 @@ } } }, - { - "type": "object", - "additionalProperties": false, - "required": [ - "kind", - "columns", - "cells", - "iterations", - "weighted", - "scope" - ], - "properties": { - "kind": { - "const": "rake_to_vendored_facts" - }, - "columns": { - "type": "array", - "items": { - "type": "string" - } - }, - "iterations": { - "type": "integer", - "minimum": 1 - }, - "weighted": { - "type": "boolean" - }, - "scope": { - "enum": [ - "users_only", - "all" - ] - }, - "quintile_income": { - "type": "string" - }, - "cells": { - "type": "array", - "minItems": 1, - "items": { - "type": "object", - "additionalProperties": false, - "required": [ - "label", - "regions", - "resource", - "selector", - "allocation" - ], - "properties": { - "label": { - "type": "string" - }, - "regions": { - "type": "array", - "items": { - "type": "string" - } - }, - "resource": { - "type": "string" - }, - "selector": { - "type": "object", - "additionalProperties": false, - "required": [ - "concept", - "fiscal_start" - ], - "properties": { - "concept": { - "type": "string" - }, - "fiscal_start": { - "type": "string" - }, - "geography_id": { - "type": "string" - }, - "groupby_value_id": { - "type": "string" - }, - "dimension_values": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "sum_over": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - } - } - }, - "allocation": { - "enum": [ - "uniform", - "income_quintile_trips" - ] - }, - "allocation_resource": { - "type": "string" - }, - "allocation_concept": { - "type": "string" - }, - "allocation_period_value": { - "type": "integer" - }, - "joint_columns": { - "type": "array", - "minItems": 2, - "items": { - "type": "string" - } - } - } - } - } - } - }, { "type": "object", "additionalProperties": false, @@ -9505,11 +9378,12 @@ "pricing_areas", "unpriced_regions", "support_areas", + "raw_draw_regions", "basis" ], "properties": { "kind": { - "const": "record_support_per_journey" + "const": "price_bus_support" }, "support_column": { "type": "string" @@ -9893,6 +9767,12 @@ }, "basis": { "type": "string" + }, + "raw_draw_regions": { + "type": "array", + "items": { + "type": "string" + } } } } diff --git a/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json b/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json index 225dee5a2..3e8c98b0b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json +++ b/packages/microcosm-build/src/microcosm/build/uk/devolved_bus_finance.json @@ -6,7 +6,8 @@ "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets; DfI Northern Ireland Translink full-fare concession passenger journeys by fiscal year (the concessionary split for the Northern Ireland bus price).", "consumers": [ "uk_runtime.lcfs_consumption", - "uk_runtime.etb_services" + "uk_runtime.etb_services", + "uk_runtime.bus_support_pricing" ], "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", diff --git a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json index 863f42d4e..ed3cbec36 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json +++ b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json @@ -8,7 +8,7 @@ "uk_runtime.lcfs_consumption", "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", - "uk_runtime.bus_support_per_journey" + "uk_runtime.bus_support_pricing" ], "planned_consumers": [], "policy": "Rows are copied verbatim from the pinned Chronicle consumer feed named in source_fact_feed; every value is a publisher-stated fact. Consumers declare their own arithmetic on these rows and never edit this file by hand: regenerate it with tools/vendor_uk_ledger_facts.py.", diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 634437575..5443538eb 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -356,7 +356,7 @@ "notes": "Stage-time support-clip health gate over the ETB services receipt. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus support is exempt since microcosm#890: the declared rake to the published net support sets its level." }, { - "id": "uk_stage_etb_services_support_rake", + "id": "uk_stage_etb_services_support_pricing", "gate": "stage_health", "phase": "transferred", "criticality": "release_blocking", @@ -364,17 +364,10 @@ "population_fact_check": true, "parameters": { "stage": "etb_services", - "check": "fact_rake", - "receipt_key": "bus_support_rake", - "maximum_relative_deviation": 1e-06, - "allowed_resources": [ - "orr_rail_facts.json", - "dft_bus_value_anchors.json", - "devolved_bus_finance.json", - "dft_bus_journeys.json" - ] + "check": "bus_support_pricing", + "maximum_relative_deviation": 1e-09 }, - "notes": "Stage-time fact check on the ETB bus-support rake receipt (microcosm#930 C7; the #890 rake had no fence): every cell's published net support (DfT BUS05bi for London and England outside London, Scottish Transport Statistics, StatsWales, and the NITHC bus-plus-rail joint cell) is recomputed from the vendored rows through the stage's own declaration and must equal the receipt's, and each cell's design-weighted total after the rake must equal its published value (a joint cell over the sum of its columns); a skipped cell fails closed. A population fact check: the synthetic smoke records it without blocking. The stage also records, unfenced, what pricing support from the frame's journeys would give (support_per_journey), for María's ruling on retiring this rake." + "notes": "Stage-time fact check on the ETB bus-support pricing receipt (microcosm#930; the #890 rake to the published net support retired on María's ruling of 2026-09-23): every declared support area's concessionary travel reimbursement, net support, boardings and concessionary boardings (DfT BUS05bi and BUS01 for London and England outside London, Scottish Transport Statistics for Scotland) and the per-boarding rates derived from them are recomputed from the vendored rows through the stage's own declaration and must equal the receipt's; the raw-draw regions (Wales, Northern Ireland) must be the declared ones and the pricing must be applied on the chain's raw draw. The priced support against the published net support is reported, not fenced: the calibration targets act on it. A population fact check: the synthetic smoke records it without blocking." }, { "id": "uk_stage_frs_hmrc_spine_leaves_signal", diff --git a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json index 059c8cd7a..4b6e267f6 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json @@ -284,7 +284,8 @@ "purpose": "Scotland bus and coach statistics (2024 and 2025 editions: journeys, passenger revenue, operator revenue, government support components, fare index); Welsh local authority roads and transport revenue outturn public transport lines for the Wales total; Northern Ireland Transport Holding Company transactions with DfI; DfI Translink bus journeys and passenger receipts by service. Consumed by the devolved cells of the bus-fare and bus-support rakes and the country-leg bus targets; DfI Northern Ireland Translink full-fare concession passenger journeys by fiscal year (the concessionary split for the Northern Ireland bus price).", "consumers": [ "uk_runtime.lcfs_consumption", - "uk_runtime.etb_services" + "uk_runtime.etb_services", + "uk_runtime.bus_support_pricing" ], "planned_consumers": [], "selections": [ @@ -588,7 +589,7 @@ "uk_runtime.lcfs_consumption", "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", - "uk_runtime.bus_support_per_journey" + "uk_runtime.bus_support_pricing" ], "planned_consumers": [], "selections": [ 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 baedb18dd..495d32403 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -2597,118 +2597,10 @@ }, { "kind": "support_clip", - "range": "donor_realized", - "exempt": [ - "bus_subsidy_spending" - ] - }, - { - "kind": "rake_to_vendored_facts", - "columns": [ - "bus_subsidy_spending" - ], - "scope": "all", - "iterations": 1, - "weighted": true, - "cells": [ - { - "label": "london", - "regions": [ - "LONDON" - ], - "resource": "dft_bus_value_anchors.json", - "selector": { - "concept": "dft.local_bus_total_estimated_net_support", - "fiscal_start": "2024-04-01", - "geography_id": "E12000007" - }, - "allocation": "uniform" - }, - { - "label": "england_outside_london", - "regions": [ - "NORTH_EAST", - "NORTH_WEST", - "YORKSHIRE", - "EAST_MIDLANDS", - "WEST_MIDLANDS", - "EAST_OF_ENGLAND", - "SOUTH_EAST", - "SOUTH_WEST" - ], - "resource": "dft_bus_value_anchors.json", - "selector": { - "concept": "dft.local_bus_total_estimated_net_support", - "fiscal_start": "2024-04-01", - "geography_id": "dft:england_outside_london" - }, - "allocation": "uniform" - }, - { - "label": "scotland", - "regions": [ - "SCOTLAND" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "scotgov.bus.government_support", - "fiscal_start": "2024-04-01", - "dimension_values": { - "funding_component": "all_government_support" - } - }, - "allocation": "uniform" - }, - { - "label": "wales", - "regions": [ - "WALES" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "welshgov.local_transport.gross_expenditure", - "fiscal_start": "2024-04-01", - "dimension_values": { - "expenditure_component": "Gross expenditure" - }, - "sum_over": { - "service_line": [ - "Concessionary fares", - "Support to operators" - ] - } - }, - "allocation": "uniform" - }, - { - "label": "northern_ireland", - "regions": [ - "NORTHERN_IRELAND" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "nithc.dfi_transaction_value", - "fiscal_start": "2024-04-01", - "dimension_values": { - "mode_scope": "all_public_transport" - }, - "sum_over": { - "funding_component": [ - "Public Service Obligation compensation", - "Concessionary fare compensation for a range of groups" - ] - } - }, - "allocation": "uniform", - "joint_columns": [ - "bus_subsidy_spending", - "rail_subsidy_spending" - ] - } - ] + "range": "donor_realized" }, { - "kind": "record_support_per_journey", + "kind": "price_bus_support", "support_column": "bus_subsidy_spending", "trips_columns": { "bus_in_london": "bus_in_london_trips", @@ -2801,10 +2693,42 @@ "E12000008", "E12000009" ] + }, + { + "label": "scotland", + "series": "other_local_bus", + "regions": [ + "SCOTLAND" + ], + "receipts": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.operator_revenue", + "groupby_value_id": "passenger_revenue", + "dimension_values": { + "revenue_component": "passenger_revenue" + } + }, + "boardings": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys" + }, + "concessionary": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "concessionary_passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + } + }, + "trips_concept": "dft.other_local_bus_trips_per_person", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "population_geography_ids": [ + "S92000003" + ] } ], "unpriced_regions": [ - "SCOTLAND", "WALES", "NORTHERN_IRELAND" ], @@ -2873,9 +2797,46 @@ "journey_category": "total_concessionary" } } + }, + { + "label": "scotland", + "regions": [ + "SCOTLAND" + ], + "reimbursement": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.government_support", + "dimension_values": { + "funding_component": "concessionary_fares" + } + }, + "net_support": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.government_support", + "dimension_values": { + "funding_component": "all_government_support" + } + }, + "boardings": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys" + }, + "concessionary": { + "resource": "devolved_bus_finance.json", + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "concessionary_passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + } + } } ], - "basis": "value-side alternative recorded beside the raked column, never applied (microcosm#930, María's ruling pending); England only, where DfT publishes the reimbursement and net support by area" + "raw_draw_regions": [ + "WALES", + "NORTHERN_IRELAND" + ], + "basis": "bus support priced from the frame's journeys at the published support per boarding where the publisher gives the components and the boardings (DfT BUS05bi and BUS01 for London and England outside London, Scottish Transport Statistics for Scotland); 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, as Wales fares do (microcosm#930; María's ruling of 2026-09-23 retiring the support rake)" }, { "kind": "compute_ratio", @@ -2923,7 +2884,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 support rake levels away in every nation and which therefore only positions the donor before the QRF), rakes bus support so each area's design-weighted total equals the FY2024-25 published net support (DfT BUS05bi for London and England outside London, Scottish Transport Statistics all government support, the StatsWales local-authority gross expenditure on concessionary fares plus support to operators for Wales, and for Northern Ireland the NITHC accounts' PSO plus concessionary compensation bound jointly on bus plus rail support since the accounts carry no split; microcosm#890 D), with the raked column exempt from the support clip, 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" }, { "stage": "frs_hmrc_spine_leaves", 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 1ef184926..517b1ebd9 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1975,82 +1975,7 @@ stages: n_estimators: 100 - kind: support_clip range: donor_realized - exempt: - - bus_subsidy_spending - - kind: rake_to_vendored_facts - columns: - - bus_subsidy_spending - scope: all - iterations: 1 - weighted: true - cells: - - label: london - regions: - - LONDON - resource: dft_bus_value_anchors.json - selector: - concept: dft.local_bus_total_estimated_net_support - fiscal_start: '2024-04-01' - geography_id: E12000007 - allocation: uniform - - label: england_outside_london - regions: - - NORTH_EAST - - NORTH_WEST - - YORKSHIRE - - EAST_MIDLANDS - - WEST_MIDLANDS - - EAST_OF_ENGLAND - - SOUTH_EAST - - SOUTH_WEST - resource: dft_bus_value_anchors.json - selector: - concept: dft.local_bus_total_estimated_net_support - fiscal_start: '2024-04-01' - geography_id: dft:england_outside_london - allocation: uniform - - label: scotland - regions: - - SCOTLAND - resource: devolved_bus_finance.json - selector: - concept: scotgov.bus.government_support - fiscal_start: '2024-04-01' - dimension_values: - funding_component: all_government_support - allocation: uniform - - label: wales - regions: - - WALES - resource: devolved_bus_finance.json - selector: - concept: welshgov.local_transport.gross_expenditure - fiscal_start: '2024-04-01' - dimension_values: - expenditure_component: Gross expenditure - sum_over: - service_line: - - Concessionary fares - - Support to operators - allocation: uniform - - label: northern_ireland - regions: - - NORTHERN_IRELAND - resource: devolved_bus_finance.json - selector: - concept: nithc.dfi_transaction_value - fiscal_start: '2024-04-01' - dimension_values: - mode_scope: all_public_transport - sum_over: - funding_component: - - Public Service Obligation compensation - - Concessionary fare compensation for a range of groups - allocation: uniform - joint_columns: - - bus_subsidy_spending - - rail_subsidy_spending - - kind: record_support_per_journey + - kind: price_bus_support support_column: bus_subsidy_spending trips_columns: bus_in_london: bus_in_london_trips @@ -2128,8 +2053,31 @@ stages: - E12000007 - E12000008 - E12000009 + - label: scotland + series: other_local_bus + regions: + - SCOTLAND + receipts: + resource: devolved_bus_finance.json + concept: scotgov.bus.operator_revenue + groupby_value_id: passenger_revenue + dimension_values: + revenue_component: passenger_revenue + boardings: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: all_passenger_journeys + concessionary: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: concessionary_passenger_journeys + dimension_values: + journey_category: concessionary + trips_concept: dft.other_local_bus_trips_per_person + trips_basis: england_other_local_bus_rate_as_proxy + population_geography_ids: + - S92000003 unpriced_regions: - - SCOTLAND - WALES - NORTHERN_IRELAND support_areas: @@ -2182,7 +2130,33 @@ stages: geography_id: dft:england_outside_london dimension_values: journey_category: total_concessionary - basis: value-side alternative recorded beside the raked column, never applied (microcosm#930, María's ruling pending); England only, where DfT publishes the reimbursement and net support by area + - label: scotland + regions: + - SCOTLAND + reimbursement: + resource: devolved_bus_finance.json + concept: scotgov.bus.government_support + dimension_values: + funding_component: concessionary_fares + net_support: + resource: devolved_bus_finance.json + concept: scotgov.bus.government_support + dimension_values: + funding_component: all_government_support + boardings: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: all_passenger_journeys + concessionary: + resource: devolved_bus_finance.json + concept: scotgov.bus.passenger_journeys + groupby_value_id: concessionary_passenger_journeys + dimension_values: + journey_category: concessionary + raw_draw_regions: + - WALES + - NORTHERN_IRELAND + basis: bus support priced from the frame's journeys at the published support per boarding where the publisher gives the components and the boardings (DfT BUS05bi and BUS01 for London and England outside London, Scottish Transport Statistics for Scotland); 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, as Wales fares do (microcosm#930; María's ruling of 2026-09-23 retiring the support rake) - kind: compute_ratio output: rail_usage numerator: rail_subsidy_spending @@ -2220,7 +2194,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 support rake levels away in every nation and which therefore only positions the donor before the QRF), rakes bus support so each area's design-weighted total equals the FY2024-25 published net support (DfT BUS05bi for London and England outside London, Scottish Transport Statistics all government support, the StatsWales local-authority gross expenditure on concessionary fares plus support to operators for Wales, and for Northern Ireland the NITHC accounts' PSO plus concessionary compensation bound jointly on bus plus rail support since the accounts carry no split; microcosm#890 D), with the raked column exempt from the support clip, 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. - stage: frs_hmrc_spine_leaves survey: Family Resources Survey 2024-25 source: Department for Work and Pensions Family Resources Survey 2024-25 raw adult.tab and benefits.tab, caller-supplied local input 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 23039c8dd..36243c567 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 @@ -1631,9 +1631,6 @@ def _ledger_compile_parity_required_artifacts( "trip_rates_period_value", "maximum_user_share_deviation", "maximum_trip_rate_deviation", - # #930 fact_rake check on a declared rake receipt. - "receipt_key", - "allowed_resources", } ), artifact_keys=frozenset({"stage_evidence"}), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py deleted file mode 100644 index 27ebc11b1..000000000 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_per_journey.py +++ /dev/null @@ -1,195 +0,0 @@ -"""What a value-side treatment of bus support would give, recorded not applied. - -The ETB stage rakes ``bus_subsidy_spending`` to the published net support per -area and calibration binds the same facts (the rake-then-bind shape microcosm#930 -retires for fares). This diagnostic records, per residence area, what the -support would be if it were priced from the frame's journeys the way fares now -are: the published concessionary travel reimbursement per concessionary -boarding times the frame's eligible boardings, plus the rest of the net -support per boarding times every boarding, beside the raked column's -design-weighted total. Boardings are the ``nts_bus_travel`` trips times the -boardings-per-resident-trip translation of the fare pricing (the same -published BUS01 over NTS0705a times population), so the two columns share -one quantity. Every input is a vendored Chronicle row (the BUS01 journeys, -concessionary journeys and BUS05 reimbursement in ``dft_bus_journeys.json``, -the net support in ``dft_bus_value_anchors.json``); nothing here changes a -value — the switch is María's ruling with these numbers in hand. -""" - -from __future__ import annotations - -from collections.abc import Mapping, Sequence -from typing import Any - -import numpy as np -import pandas as pd - -from microcosm.build.uk_runtime.bus_fare_pricing import ( - BUS_IN_LONDON, - OTHER_LOCAL_BUS, - BusFarePricingError, - bus_fare_prices, - published_fact, -) - -RECORD_SUPPORT_PER_JOURNEY_KIND = "record_support_per_journey" - - -def support_per_journey_diagnostic( - parameters: Mapping[str, Any], - *, - person: pd.DataFrame, - household: pd.DataFrame, - household_weights: np.ndarray, - raked_support: np.ndarray, - allowed_resources: Sequence[str], -) -> dict[str, Any]: - """The receipt of the value-side alternative, per declared residence area.""" - - if parameters.get("kind", RECORD_SUPPORT_PER_JOURNEY_KIND) != ( - RECORD_SUPPORT_PER_JOURNEY_KIND - ): - raise BusFarePricingError("not a record_support_per_journey declaration.") - pricing = { - "kind": "price_bus_journeys", - "column": "bus_fare_spending", - "trips_columns": dict(parameters["trips_columns"]), - "eligibility_column": str(parameters["eligibility_column"]), - "fiscal_start": str(parameters["fiscal_start"]), - "trip_rates_resource": str(parameters["trip_rates_resource"]), - "trip_rates_period_value": int(parameters["trip_rates_period_value"]), - "population_resource": str(parameters["population_resource"]), - "population_period_value": int(parameters["population_period_value"]), - "areas": list(parameters["pricing_areas"]), - "unpriced_regions": list(parameters.get("unpriced_regions", ())), - } - prices = bus_fare_prices(pricing, allowed_resources=allowed_resources) - trips_columns = { - str(k): str(v) for k, v in dict(parameters["trips_columns"]).items() - } - eligibility = str(parameters["eligibility_column"]) - support_column = str(parameters["support_column"]) - for column in ("person_household_id", eligibility, *trips_columns.values()): - if column not in person: - raise BusFarePricingError( - f"the person table lacks {column!r}; the nts_bus_travel stage must run first." - ) - weights = np.asarray(household_weights, dtype=float) - region_by_household = household.set_index("household_id")["region"].map( - lambda v: str(getattr(v, "name", v)) - ) - hh_ids = person["person_household_id"].to_numpy() - person_region = region_by_household.reindex(hh_ids).to_numpy().astype(str) - person_weight = ( - pd.Series(weights, index=household["household_id"].to_numpy()) - .reindex(hh_ids) - .fillna(0.0) - .to_numpy(dtype=float) - ) - eligible = person[eligibility].to_numpy(dtype=bool) - london_trips = person[trips_columns[BUS_IN_LONDON]].to_numpy(dtype=float) - other_trips = person[trips_columns[OTHER_LOCAL_BUS]].to_numpy(dtype=float) - k_london = prices.london.boardings_per_trip - household_region = ( - household["region"].map(lambda v: str(getattr(v, "name", v))).to_numpy() - ) - raked = np.asarray(raked_support, dtype=float) - by_area: dict[str, dict[str, Any]] = {} - for area in parameters["support_areas"]: - area = dict(area) - label = str(area["label"]) - regions = tuple(str(r) for r in area["regions"]) - fiscal_start = str(parameters["fiscal_start"]) - reimbursement, reimbursement_receipt = published_fact( - dict(area["reimbursement"]), - unit="gbp", - allowed_resources=allowed_resources, - fiscal_start=fiscal_start, - ) - net_support, net_support_receipt = published_fact( - dict(area["net_support"]), - unit="gbp", - allowed_resources=allowed_resources, - fiscal_start=fiscal_start, - ) - boardings, boardings_receipt = published_fact( - dict(area["boardings"]), - unit="count", - allowed_resources=allowed_resources, - fiscal_start=fiscal_start, - ) - concessionary, concessionary_receipt = published_fact( - dict(area["concessionary"]), - unit="count", - allowed_resources=allowed_resources, - fiscal_start=fiscal_start, - ) - if net_support < reimbursement: - raise BusFarePricingError( - f"area {label!r}: net support {net_support} is below the concessionary " - f"reimbursement {reimbursement} it contains." - ) - reimbursement_per_concessionary_boarding = reimbursement / concessionary - other_support_per_boarding = (net_support - reimbursement) / boardings - mask = np.isin(person_region, regions) - # Boardings of the area's residents: each series at its own translation. - k_other = np.zeros(len(person), dtype=float) - for region in regions: - price = prices.area_for_region(region) - if price is None: - raise BusFarePricingError( - f"area {label!r} names {region!r}, which the pricing areas do not price." - ) - k_other[person_region == region] = price.boardings_per_trip - person_boardings = london_trips * k_london + other_trips * k_other - all_boardings = float(np.dot(person_boardings[mask], person_weight[mask])) - eligible_boardings = float( - np.dot(person_boardings[mask & eligible], person_weight[mask & eligible]) - ) - value_side = ( - reimbursement_per_concessionary_boarding * eligible_boardings - + other_support_per_boarding * all_boardings - ) - household_mask = np.isin(household_region, regions) - raked_total = float(np.dot(raked[household_mask], weights[household_mask])) - by_area[label] = { - "regions": list(regions), - "reimbursement": reimbursement_receipt, - "net_support": net_support_receipt, - "boardings": boardings_receipt, - "concessionary": concessionary_receipt, - "reimbursement_per_concessionary_boarding": reimbursement_per_concessionary_boarding, - "other_support_per_boarding": other_support_per_boarding, - "frame_boardings": all_boardings, - "frame_eligible_boardings": eligible_boardings, - "frame_eligible_boarding_share": ( - eligible_boardings / all_boardings if all_boardings > 0 else None - ), - "published_concessionary_boarding_share": concessionary / boardings, - "value_side_support": value_side, - "raked_support": raked_total, - "value_side_over_raked": ( - value_side / raked_total if raked_total > 0 else None - ), - "households": int(household_mask.sum()), - "persons": int(mask.sum()), - } - return { - "operation": RECORD_SUPPORT_PER_JOURNEY_KIND, - "support_column": support_column, - "applied": False, - "basis": ( - "reimbursement per concessionary boarding times the frame's eligible " - "boardings plus the rest of the net support per boarding times every " - "boarding; boardings are nts_bus_travel trips times the fare pricing's " - "boardings per resident trip" - ), - "boardings_per_trip": { - "bus_in_london": k_london, - **{ - a.label: a.boardings_per_trip - for a in {a.label: a for a in prices.other_by_region.values()}.values() - }, - }, - "by_area": by_area, - } diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_pricing.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_pricing.py new file mode 100644 index 000000000..aa8db7d5d --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/bus_support_pricing.py @@ -0,0 +1,267 @@ +"""Bus support priced from the frame's journeys at the published support per boarding. + +The ETB stage used to rake ``bus_subsidy_spending`` to the published net +support per area while calibration bound the same facts, the rake-then-bind +shape microcosm#930 retired for fares; María's ruling of 2026-09-23 retires it +for support too. Each priced area's household support is the published +concessionary travel reimbursement per concessionary boarding times the +household's eligible persons' boardings, plus the rest of the published net +support per boarding times every boarding of the household; boardings are the +``nts_bus_travel`` trips times the fare pricing's boardings-per-resident-trip +translation (BUS01 over NTS0705a times population), so fares and support +share one quantity. Areas the publisher gives no components or boardings for +(Wales, Northern Ireland: the NITHC accounts carry bus and rail jointly and +no Welsh boardings are published) keep the ETB chain's raw draw, clipped to +donor support, as Wales fares do. Every input is a vendored Chronicle row (the +BUS01 journeys, concessionary journeys and BUS05 components in +``dft_bus_journeys.json``, the net support in ``dft_bus_value_anchors.json``, +the Scottish components and journeys in ``devolved_bus_finance.json``); the +published totals stay bound as calibration targets, which now measure the +priced quantity instead of a level the stage set. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from typing import Any + +import numpy as np +import pandas as pd + +from microcosm.build.uk_runtime.bus_fare_pricing import ( + BUS_IN_LONDON, + OTHER_LOCAL_BUS, + BusFarePricingError, + bus_fare_prices, + published_fact, +) + +PRICE_BUS_SUPPORT_KIND = "price_bus_support" + + +def bus_support_pricing_operation(stage: Any) -> Mapping[str, Any] | None: + """The stage's declared ``price_bus_support`` parameters, if any.""" + + for operation in stage.operations: + if operation.kind == PRICE_BUS_SUPPORT_KIND: + return {"kind": operation.kind, **operation.parameters} + return None + + +def _pricing_parameters(parameters: Mapping[str, Any]) -> dict[str, Any]: + return { + "kind": "price_bus_journeys", + "column": "bus_fare_spending", + "trips_columns": dict(parameters["trips_columns"]), + "eligibility_column": str(parameters["eligibility_column"]), + "fiscal_start": str(parameters["fiscal_start"]), + "trip_rates_resource": str(parameters["trip_rates_resource"]), + "trip_rates_period_value": int(parameters["trip_rates_period_value"]), + "population_resource": str(parameters["population_resource"]), + "population_period_value": int(parameters["population_period_value"]), + "areas": list(parameters["pricing_areas"]), + "unpriced_regions": list(parameters.get("unpriced_regions", ())), + } + + +def bus_support_factors( + parameters: Mapping[str, Any], *, allowed_resources: Sequence[str] +) -> dict[str, dict[str, Any]]: + """Every declared support area's published components and per-boarding rates. + + Recomputed from the vendored rows by the stage and by its gate alike, so + the receipt can never carry a factor the rows do not give. + """ + + fiscal_start = str(parameters["fiscal_start"]) + factors: dict[str, dict[str, Any]] = {} + for area in parameters["support_areas"]: + area = dict(area) + label = str(area["label"]) + values: dict[str, float] = {} + receipts: dict[str, Any] = {} + for key, unit in ( + ("reimbursement", "gbp"), + ("net_support", "gbp"), + ("boardings", "count"), + ("concessionary", "count"), + ): + values[key], receipts[key] = published_fact( + dict(area[key]), + unit=unit, + allowed_resources=allowed_resources, + fiscal_start=fiscal_start, + ) + if values["net_support"] < values["reimbursement"]: + raise BusFarePricingError( + f"area {label!r}: net support {values['net_support']} is below the " + f"concessionary reimbursement {values['reimbursement']} it contains." + ) + if values["concessionary"] <= 0 or values["boardings"] <= 0: + raise BusFarePricingError(f"area {label!r}: boardings must be positive.") + factors[label] = { + "regions": [str(r) for r in area["regions"]], + **receipts, + "reimbursement_per_concessionary_boarding": ( + values["reimbursement"] / values["concessionary"] + ), + "other_support_per_boarding": ( + (values["net_support"] - values["reimbursement"]) / values["boardings"] + ), + "published_concessionary_boarding_share": ( + values["concessionary"] / values["boardings"] + ), + } + return factors + + +def price_bus_support( + parameters: Mapping[str, Any], + *, + person: pd.DataFrame, + household: pd.DataFrame, + household_weights: np.ndarray, + raw_support: np.ndarray, + allowed_resources: Sequence[str], +) -> tuple[np.ndarray, np.ndarray, dict[str, Any]]: + """Household bus support: priced per declared area, the raw draw elsewhere. + + Returns the household values, the mask of priced households and the + receipt. A region that is neither in a support area nor declared a + ``raw_draw_regions`` member is refused. + """ + + if parameters.get("kind", PRICE_BUS_SUPPORT_KIND) != PRICE_BUS_SUPPORT_KIND: + raise BusFarePricingError("not a price_bus_support declaration.") + prices = bus_fare_prices( + _pricing_parameters(parameters), allowed_resources=allowed_resources + ) + factors = bus_support_factors(parameters, allowed_resources=allowed_resources) + raw_draw_regions = frozenset(str(r) for r in parameters.get("raw_draw_regions", ())) + trips_columns = { + str(k): str(v) for k, v in dict(parameters["trips_columns"]).items() + } + eligibility = str(parameters["eligibility_column"]) + support_column = str(parameters["support_column"]) + for column in ("person_household_id", eligibility, *trips_columns.values()): + if column not in person: + raise BusFarePricingError( + f"the person table lacks {column!r}; the nts_bus_travel stage must run first." + ) + weights = np.asarray(household_weights, dtype=float) + region_by_household = household.set_index("household_id")["region"].map( + lambda v: str(getattr(v, "name", v)) + ) + hh_ids = person["person_household_id"].to_numpy() + person_region = region_by_household.reindex(hh_ids).to_numpy().astype(str) + person_weight = ( + pd.Series(weights, index=household["household_id"].to_numpy()) + .reindex(hh_ids) + .fillna(0.0) + .to_numpy(dtype=float) + ) + eligible = person[eligibility].to_numpy(dtype=bool) + london_trips = person[trips_columns[BUS_IN_LONDON]].to_numpy(dtype=float) + other_trips = person[trips_columns[OTHER_LOCAL_BUS]].to_numpy(dtype=float) + k_london = prices.london.boardings_per_trip + household_region = ( + household["region"].map(lambda v: str(getattr(v, "name", v))).to_numpy() + ) + raw = np.asarray(raw_support, dtype=float) + values = raw.copy() + priced_household = np.zeros(len(household), dtype=bool) + covered = set(raw_draw_regions) + for block in factors.values(): + covered |= set(block["regions"]) + unknown = sorted(set(household_region) - covered) + if unknown: + raise BusFarePricingError( + f"household regions {unknown} are neither in a support area nor declared " + "raw_draw_regions." + ) + overlap = raw_draw_regions & {r for b in factors.values() for r in b["regions"]} + if overlap: + raise BusFarePricingError( + f"regions {sorted(overlap)} are both priced and declared raw_draw_regions." + ) + hh_index = pd.Series(np.arange(len(household)), index=household["household_id"]) + person_position = hh_index.reindex(hh_ids).to_numpy() + by_area: dict[str, dict[str, Any]] = {} + for label, block in factors.items(): + regions = tuple(block["regions"]) + mask = np.isin(person_region, regions) + k_other = np.zeros(len(person), dtype=float) + for region in regions: + price = prices.area_for_region(region) + if price is None: + raise BusFarePricingError( + f"area {label!r} names {region!r}, which the pricing areas do not price." + ) + k_other[person_region == region] = price.boardings_per_trip + person_boardings = london_trips * k_london + other_trips * k_other + person_support = block["other_support_per_boarding"] * person_boardings + person_support = person_support + np.where( + eligible, + block["reimbursement_per_concessionary_boarding"] * person_boardings, + 0.0, + ) + household_mask = np.isin(household_region, regions) + summed = np.zeros(len(household), dtype=float) + np.add.at(summed, person_position[mask], person_support[mask]) + values[household_mask] = summed[household_mask] + priced_household |= household_mask + all_boardings = float(np.dot(person_boardings[mask], person_weight[mask])) + eligible_boardings = float( + np.dot(person_boardings[mask & eligible], person_weight[mask & eligible]) + ) + priced_total = float(np.dot(values[household_mask], weights[household_mask])) + raw_total = float(np.dot(raw[household_mask], weights[household_mask])) + by_area[label] = { + **block, + "frame_boardings": all_boardings, + "frame_eligible_boardings": eligible_boardings, + "frame_eligible_boarding_share": ( + eligible_boardings / all_boardings if all_boardings > 0 else None + ), + "weighted_support_before": raw_total, + "weighted_support_after": priced_total, + "priced_over_published": priced_total / block["net_support"]["value"], + "households": int(household_mask.sum()), + "persons": int(mask.sum()), + } + raw_mask = np.isin(household_region, sorted(raw_draw_regions)) + receipt = { + "operation": PRICE_BUS_SUPPORT_KIND, + "support_column": support_column, + "applied": True, + "chain_conditioned_on": "raw_draw", + "basis": ( + "reimbursement per concessionary boarding times the household's eligible " + "persons' boardings plus the rest of the net support per boarding times " + "every boarding; boardings are nts_bus_travel trips times the fare " + "pricing's boardings per resident trip; regions without published " + "components or boardings keep the clipped raw draw" + ), + "boardings_per_trip": { + "bus_in_london": k_london, + **{ + a.label: a.boardings_per_trip + for a in {a.label: a for a in prices.other_by_region.values()}.values() + }, + }, + "raw_draw_regions": sorted(raw_draw_regions), + "households_priced": int(priced_household.sum()), + "households_raw_draw": int(raw_mask.sum()), + "weighted_support_before": float(np.dot(raw, weights)), + "weighted_support_after": float(np.dot(values, weights)), + "raw_draw_weighted_support": { + region: float( + np.dot( + raw[household_region == region], weights[household_region == region] + ) + ) + for region in sorted(raw_draw_regions) + }, + "by_area": by_area, + } + return values, priced_household, receipt 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 2386c475e..c666de1fc 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 @@ -139,7 +139,7 @@ class UKCalibrationRunResult: "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", - "uk_stage_etb_services_support_rake", + "uk_stage_etb_services_support_pricing", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", 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 7cf092d13..b878ab233 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 @@ -12,20 +12,16 @@ from microcosm.build.gates import FitWeightRecord from microcosm.build.source_manifest import SourceStageSpec -from microcosm.build.uk_runtime.bus_support_per_journey import ( - RECORD_SUPPORT_PER_JOURNEY_KIND, - support_per_journey_diagnostic, +from microcosm.build.uk_runtime.bus_support_pricing import ( + PRICE_BUS_SUPPORT_KIND, + bus_support_pricing_operation, + price_bus_support, ) from microcosm.build.uk_runtime.donor_uprating import ( apply_donor_uprating, donor_uprating_factors, uprating_operation, ) -from microcosm.build.uk_runtime.fact_raking import ( - rake_operations, - rake_to_facts, - resolve_cells, -) from microcosm.build.uk_runtime.frs_spine import read_pinned_tab from microcosm.build.uk_runtime.national_frame import ( uk_household_mass_conservation_receipt, @@ -118,8 +114,7 @@ class UKETBServicesResult: support_clip: UKSupportClipReceipt nhs_cells: dict[str, object] = field(default_factory=dict) donor_uprating: dict[str, object] | None = None - bus_support_rake: dict[str, object] | None = None - support_per_journey: dict[str, object] | None = None + bus_support_pricing: dict[str, object] | None = None def evidence(self) -> dict[str, object]: evidence: dict[str, object] = { @@ -129,10 +124,8 @@ def evidence(self) -> dict[str, object]: } if self.donor_uprating is not None: evidence["donor_uprating"] = dict(self.donor_uprating) - if self.bus_support_rake is not None: - evidence["bus_support_rake"] = dict(self.bus_support_rake) - if self.support_per_journey is not None: - evidence["support_per_journey"] = dict(self.support_per_journey) + if self.bus_support_pricing is not None: + evidence["bus_support_pricing"] = dict(self.bus_support_pricing) return evidence @@ -188,13 +181,7 @@ def __call__(self, frame: Frame) -> Frame: ) draws = clip_result.clipped household = frame.table("household").copy() - draws, rake_receipt = etb_bus_support_rake( - self.stage, - draws, - household=household, - weights=frame.weights_for("household").values, - ) - support_receipt = etb_support_per_journey( + draws, pricing_receipt = etb_bus_support_pricing( self.stage, draws, frame=frame, @@ -236,8 +223,7 @@ def __call__(self, frame: Frame) -> Frame: support_clip=clip_result.receipt, nhs_cells=nhs_cells, donor_uprating=uprating_receipt, - bus_support_rake=rake_receipt, - support_per_journey=support_receipt, + bus_support_pricing=pricing_receipt, ) return result @@ -476,7 +462,7 @@ def support_clip_to_donor( def support_clip_exempt(stage: SourceStageSpec) -> set[str]: - """Columns the declared ``support_clip`` exempts (a raked column keeps its level).""" + """Columns the declared ``support_clip`` exempts (none since microcosm#930).""" for operation in stage.operations: if operation.kind == "support_clip": @@ -486,86 +472,54 @@ def support_clip_exempt(stage: SourceStageSpec) -> set[str]: return set() -def etb_bus_support_rake( +def etb_bus_support_pricing( stage: SourceStageSpec, draws: pd.DataFrame, *, + frame: Frame, household: pd.DataFrame, weights: np.ndarray, ) -> tuple[pd.DataFrame, dict[str, object] | None]: - """Apply every declared ``rake_to_vendored_facts`` operation on the stage.""" - - operations = rake_operations(stage) - if not operations: - return draws, None - if "region" not in household: - raise KeyError("etb_services rake needs the household 'region' column.") - region = household["region"].map(_enum_name).to_numpy() - receipts = [] - raked = draws - for parameters in operations: - cells = resolve_cells( - parameters, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES - ) - raked, receipt = rake_to_facts( - raked, - columns=[str(column) for column in parameters["columns"]], - cells=cells, - region=np.asarray(region).astype(str), - weights=weights if bool(parameters.get("weighted", True)) else None, - scope=str(parameters["scope"]), - iterations=int(parameters.get("iterations", 1)), - ) - receipts.append(receipt) - return raked, receipts[0] if len(receipts) == 1 else {"operations": receipts} + """Price bus support from the frame's journeys where declared (microcosm#930). + The chain's clipped raw draw stands in the declared ``raw_draw_regions`` + (Wales, Northern Ireland); every other household's ``bus_subsidy_spending`` + is the published support per boarding times its persons' boardings. The + chain drew the column last, so nothing downstream conditioned on it. + """ -def etb_support_per_journey( - stage: SourceStageSpec, - draws: pd.DataFrame, - *, - frame: Frame, - household: pd.DataFrame, - weights: np.ndarray, -) -> dict[str, object] | None: - """Record what pricing support from journeys would give (microcosm#930).""" - - parameters = next( - ( - dict(operation.parameters) - for operation in stage.operations - if operation.kind == RECORD_SUPPORT_PER_JOURNEY_KIND - ), - None, - ) + parameters = bus_support_pricing_operation(stage) if parameters is None: - return None + return draws, None column = str(parameters["support_column"]) if column not in draws: raise KeyError( - f"record_support_per_journey names {column!r}, not a drawn column." + f"{PRICE_BUS_SUPPORT_KIND} names {column!r}, not a drawn column." ) - return support_per_journey_diagnostic( + values, _priced, receipt = price_bus_support( parameters, person=frame.table("person"), household=household, household_weights=np.asarray(weights, dtype=float), - raked_support=draws[column].to_numpy(dtype=float), + raw_support=draws[column].to_numpy(dtype=float), allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, ) + priced = draws.copy() + priced[column] = values + return priced, receipt -#: The declared rake levels bus support; the support clip and the committed -#: support bounds leave it alone. -UK_ETB_SERVICES_RAKED_COLUMNS = frozenset({"bus_subsidy_spending"}) +#: The declared pricing sets bus support from journeys; the committed support +#: bounds leave the column alone (the clip still bounds the raw draw first). +UK_ETB_SERVICES_PRICED_COLUMNS = frozenset({"bus_subsidy_spending"}) def donor_realized_ranges(donor: pd.DataFrame) -> dict[str, tuple[float, float]]: - """Donor support per clipped column; the raked column carries no bounds.""" + """Donor support per clipped column; the priced column carries no bounds.""" ranges = {} for column in UK_ETB_SERVICES_HOUSEHOLD_OUTPUT_COLUMNS[:3]: - if column in UK_ETB_SERVICES_RAKED_COLUMNS: + if column in UK_ETB_SERVICES_PRICED_COLUMNS: continue values = donor[column] finite = values[np.isfinite(values)] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/fact_raking.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/fact_raking.py deleted file mode 100644 index a780a5c6f..000000000 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/fact_raking.py +++ /dev/null @@ -1,492 +0,0 @@ -"""Rake imputed household columns to vendored publisher facts (microcosm#890 D). - -A ``rake_to_vendored_facts`` operation names the columns to rake and a list of -cells. Each cell is a set of FRS regions whose design-weighted total of the -column must equal one published FY2024-25 value read from a vendored Chronicle -resource (``selector``), optionally spread across household income quintiles -in proportion to the NTS trips per person by quintile (``allocation: -income_quintile_trips``) or uniformly (``allocation: uniform``). Cells are -disjoint by region; regions no cell names are left untouched (Wales fares, -whose publisher prints no receipts). - -The arithmetic is the existing cell-mean iterative proportional fit: the cell -target mean is the published value times the cell's allocation share divided -by the design-weighted households in the raking scope of that cell, so one -pass makes the weighted total equal the fact. ``scope: users_only`` restricts -the population to households a caller-supplied flag marks as users (the -take-up style incidence draw); ``scope: all`` rakes every household in the -region set. A cell may name ``joint_columns``: the published value then binds -the sum of those columns and both are scaled by one factor (Northern Ireland's -bus-plus-rail support). -""" - -from __future__ import annotations - -from collections.abc import Mapping, Sequence -from dataclasses import dataclass -from typing import Any - -import numpy as np -import pandas as pd - -from microcosm.build.raking import MarginSpec, iterative_proportional_fit -from microcosm.build.source_manifest import SourceStageSpec -from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows - -RAKE_TO_VENDORED_FACTS_KIND = "rake_to_vendored_facts" -ALLOCATION_UNIFORM = "uniform" -ALLOCATION_INCOME_QUINTILE_TRIPS = "income_quintile_trips" -SCOPE_USERS_ONLY = "users_only" -SCOPE_ALL = "all" -QUINTILE_LABELS = ("lowest", "second", "third", "fourth", "highest") -_CELL_COLUMN = "_vendored_fact_cell" -_WEIGHT_COLUMN = "_vendored_fact_weight" - - -@dataclass(frozen=True) -class FactCell: - label: str - regions: tuple[str, ...] - value: float - allocation: str - quintile_trips: Mapping[str, float] | None - joint_columns: tuple[str, ...] - receipt: dict[str, Any] - - -def rake_operations(stage: SourceStageSpec) -> list[Mapping[str, Any]]: - """Every declared ``rake_to_vendored_facts`` operation on the stage, in order.""" - - return [ - dict(operation.parameters) - for operation in stage.operations - if operation.kind == RAKE_TO_VENDORED_FACTS_KIND - ] - - -def resolve_cells( - parameters: Mapping[str, Any], *, allowed_resources: Sequence[str] -) -> list[FactCell]: - """Read every cell's published value (and allocation rows) from the vendored facts.""" - - cells: list[FactCell] = [] - seen_regions: set[str] = set() - for spec in parameters["cells"]: - label = str(spec["label"]) - regions = tuple(str(region) for region in spec["regions"]) - if not regions: - raise ValueError(f"rake cell {label!r} names no regions.") - overlap = seen_regions & set(regions) - if overlap: - raise ValueError(f"rake cell {label!r} repeats regions {sorted(overlap)}.") - seen_regions.update(regions) - resource = str(spec["resource"]) - if resource not in allowed_resources: - raise ValueError( - f"rake cell {label!r} reads {resource!r}, which this stage does " - f"not declare (allowed: {sorted(allowed_resources)})." - ) - value, value_receipt = _published_value(resource, spec["selector"]) - allocation = str(spec["allocation"]) - quintile_trips = None - allocation_receipt: dict[str, Any] = {"allocation": allocation} - if allocation == ALLOCATION_INCOME_QUINTILE_TRIPS: - allocation_resource = str(spec["allocation_resource"]) - if allocation_resource not in allowed_resources: - raise ValueError( - f"rake cell {label!r} allocation reads {allocation_resource!r}, " - "which this stage does not declare." - ) - quintile_trips, trips_receipt = _quintile_trips( - allocation_resource, - str(spec["allocation_concept"]), - int(spec["allocation_period_value"]), - ) - allocation_receipt.update(trips_receipt) - elif allocation != ALLOCATION_UNIFORM: - raise ValueError( - f"rake cell {label!r} has unknown allocation {allocation!r}." - ) - joint = tuple(str(column) for column in spec.get("joint_columns", ())) - cells.append( - FactCell( - label=label, - regions=regions, - value=value, - allocation=allocation, - quintile_trips=quintile_trips, - joint_columns=joint, - receipt={ - "label": label, - "regions": list(regions), - "resource": resource, - **value_receipt, - **allocation_receipt, - **({"joint_columns": list(joint)} if joint else {}), - }, - ) - ) - return cells - - -def _published_value( - resource: str, selector: Mapping[str, Any] -) -> tuple[float, dict[str, Any]]: - criteria: dict[str, Any] = {"concept": str(selector["concept"])} - for key in ("geography_id", "groupby_value_id"): - if selector.get(key): - criteria[key] = str(selector[key]) - if selector.get("dimension_values"): - criteria["dimensions"] = { - str(k): str(v) for k, v in dict(selector["dimension_values"]).items() - } - rows = vendored_rows( - resource, fiscal_start=str(selector["fiscal_start"]), **criteria - ) - sum_over = dict(selector.get("sum_over") or {}) - if sum_over: - if len(sum_over) != 1: - raise ValueError("sum_over names exactly one dimension.") - ((dimension, values),) = sum_over.items() - wanted = [str(v) for v in values] - rows = [ - row - for row in rows - if str((row.get("dimensions") or {}).get(dimension)) in wanted - ] - found = sorted( - str((row.get("dimensions") or {}).get(dimension)) for row in rows - ) - if found != sorted(wanted): - raise ValueError( - f"{resource}: sum_over {dimension!r} expected {sorted(wanted)}, " - f"found {found}." - ) - elif len(rows) != 1: - raise ValueError( - f"{resource}: expected exactly one row for {selector}, found {len(rows)}." - ) - value = float(sum(float(row["value"]) for row in rows)) - if not np.isfinite(value) or value <= 0: - raise ValueError( - f"{resource}: published value for {selector} must be positive." - ) - units = {str(row.get("unit")) for row in rows} - if units != {"gbp"}: - raise ValueError(f"{resource}: expected gbp rows for {selector}, got {units}.") - return value, { - "selector": {k: v for k, v in selector.items()}, - "value": value, - "source_record_ids": [str(row.get("source_record_id", "")) for row in rows], - } - - -def _quintile_trips( - resource: str, concept: str, period_value: int -) -> tuple[dict[str, float], dict[str, Any]]: - trips: dict[str, float] = {} - record_ids: list[str] = [] - for quintile in QUINTILE_LABELS: - rows = vendored_rows( - resource, - concept=concept, - period_type="calendar_year", - period_value=period_value, - dimensions={"household_income_quintile": quintile}, - ) - if len(rows) != 1: - raise ValueError( - f"{resource}: expected one {concept} row for quintile {quintile!r} " - f"in {period_value}, found {len(rows)}." - ) - value = float(rows[0]["value"]) - if not np.isfinite(value) or value <= 0: - raise ValueError(f"{resource}: trips per person must be positive.") - trips[quintile] = value - record_ids.append(str(rows[0].get("source_record_id", ""))) - return trips, { - "allocation_resource": resource, - "allocation_concept": concept, - "allocation_period_value": period_value, - "trips_per_person_by_quintile": dict(trips), - "allocation_source_record_ids": record_ids, - } - - -def person_income_quintiles( - household_income: np.ndarray, - household_persons: np.ndarray, - weights: np.ndarray, - *, - mask: np.ndarray, -) -> tuple[np.ndarray, list[float]]: - """Design-weighted person quintiles of household income over ``mask`` rows. - - Returns each household's quintile label (empty string outside ``mask``) and - the four internal edges. Persons, not households, are ranked (the NTS - quintiles are of people by their household income), so a household's - weight is its design weight times its size. - """ - - income = np.asarray(household_income, dtype=float) - persons = np.asarray(household_persons, dtype=float) - weights = np.asarray(weights, dtype=float) - mask = np.asarray(mask, dtype=bool) - labels = np.full(len(income), "", dtype=object) - if not mask.any(): - return labels, [] - order = np.argsort(income[mask], kind="stable") - masked_income = income[mask][order] - masked_weight = (weights[mask] * persons[mask])[order] - total = float(masked_weight.sum()) - if total <= 0: - raise ValueError("income quintiles need positive weighted persons.") - cumulative = np.cumsum(masked_weight) / total - edges = [ - float( - masked_income[ - min( - int(np.searchsorted(cumulative, q, side="right")), - len(masked_income) - 1, - ) - ] - ) - for q in (0.2, 0.4, 0.6, 0.8) - ] - position = np.searchsorted(np.asarray(edges), income[mask], side="right") - labels[mask] = np.asarray(QUINTILE_LABELS, dtype=object)[position] - return labels, edges - - -def rake_to_facts( - household: pd.DataFrame, - *, - columns: Sequence[str], - cells: Sequence[FactCell], - region: Sequence[str], - weights: Sequence[float] | None, - scope: str, - users: Sequence[bool] | None = None, - quintile_income: Sequence[float] | None = None, - household_persons: Sequence[float] | None = None, - iterations: int = 1, -) -> tuple[pd.DataFrame, dict[str, Any]]: - """Scale ``columns`` so each cell's weighted total equals its published value.""" - - if scope not in (SCOPE_USERS_ONLY, SCOPE_ALL): - raise ValueError(f"unknown rake scope {scope!r}.") - frame = household.copy() - n = len(frame) - region_values = np.asarray(region).astype(str) - if len(region_values) != n: - raise ValueError("region must align with the household table.") - weight_values = ( - np.ones(n, dtype=float) if weights is None else np.asarray(weights, dtype=float) - ) - if scope == SCOPE_USERS_ONLY: - if users is None: - raise ValueError("scope users_only needs the user flag.") - in_scope = np.asarray(users, dtype=bool) - else: - in_scope = np.ones(n, dtype=bool) - needs_quintiles = any( - cell.allocation == ALLOCATION_INCOME_QUINTILE_TRIPS for cell in cells - ) - quintile_labels = np.full(n, "", dtype=object) - quintile_edges: list[float] = [] - if needs_quintiles: - if quintile_income is None or household_persons is None: - raise ValueError( - "income_quintile_trips allocation needs quintile_income and " - "household_persons." - ) - quintile_regions = { - r - for cell in cells - if cell.allocation == ALLOCATION_INCOME_QUINTILE_TRIPS - for r in cell.regions - } - quintile_labels, quintile_edges = person_income_quintiles( - np.asarray(quintile_income, dtype=float), - np.asarray(household_persons, dtype=float), - weight_values, - mask=np.isin(region_values, sorted(quintile_regions)), - ) - cell_column = np.full(n, "", dtype=object) - targets: dict[str, dict[str, float]] = {} - cell_receipts: list[dict[str, Any]] = [] - joint_receipts: list[dict[str, Any]] = [] - skipped_cells: list[dict[str, Any]] = [] - for cell in cells: - member = np.isin(region_values, list(cell.regions)) - population = member & in_scope - if not member.any(): - # No household of the frame lives in the cell's regions (a partial - # or synthetic frame): the published mass has nowhere to go and the - # cell is skipped, receipted, like an empty IPF cell. A populated - # region with nobody in scope is refused below instead. - skipped_cells.append( - { - "cell": cell.label, - "regions": list(cell.regions), - "target_total": cell.value, - "reason": "no households in the cell's regions", - } - ) - continue - if cell.joint_columns: - frame, receipt = _rake_joint( - frame, cell, population, weight_values, list(cell.joint_columns) - ) - joint_receipts.append(receipt) - continue - if cell.allocation == ALLOCATION_UNIFORM: - shares = {cell.label: 1.0} - groups = {cell.label: population} - else: - assert cell.quintile_trips is not None - persons = np.asarray(household_persons, dtype=float) - weighted_persons = { - q: float( - (weight_values * persons)[member & (quintile_labels == q)].sum() - ) - for q in QUINTILE_LABELS - } - raw_shares = { - q: weighted_persons[q] * cell.quintile_trips[q] for q in QUINTILE_LABELS - } - total_share = sum(raw_shares.values()) - if total_share <= 0: - raise ValueError( - f"rake cell {cell.label!r} has no persons to allocate." - ) - shares = {q: raw_shares[q] / total_share for q in QUINTILE_LABELS} - groups = {q: population & (quintile_labels == q) for q in QUINTILE_LABELS} - for key, group in groups.items(): - name = cell.label if key == cell.label else f"{cell.label}:{key}" - cell_column[group] = name - households = float(weight_values[group].sum()) - target_total = cell.value * shares[key] - if households <= 0: - if target_total > 0: - raise ValueError( - f"rake cell {name!r} carries GBP {target_total:,.0f} but " - "has no households in scope." - ) - continue - target_mean = target_total / households - targets[name] = {column: target_mean for column in columns} - before = { - column: float( - np.dot( - pd.to_numeric(frame[column], errors="coerce") - .fillna(0.0) - .to_numpy(dtype=float)[group], - weight_values[group], - ) - ) - for column in columns - } - cell_receipts.append( - { - "cell": name, - "label": cell.label, - **({"quintile": key} if key != cell.label else {}), - "share": shares[key], - "target_total": target_total, - "weighted_households_in_scope": households, - "weighted_total_before": before, - "factor": { - column: (target_total / before[column]) - if before[column] > 0 - else None - for column in columns - }, - } - ) - frame[_CELL_COLUMN] = cell_column - frame[_WEIGHT_COLUMN] = weight_values - if targets: - frame = iterative_proportional_fit( - frame, - columns=tuple(columns), - margins=(MarginSpec(_CELL_COLUMN, targets),), - iterations=iterations, - weight_column=_WEIGHT_COLUMN, - fail_on_unattainable=True, - ) - for entry in cell_receipts: - group = frame[_CELL_COLUMN].to_numpy() == entry["cell"] - entry["weighted_total_after"] = { - column: float( - np.dot(frame[column].to_numpy(dtype=float)[group], weight_values[group]) - ) - for column in columns - } - raked = frame.drop(columns=[_CELL_COLUMN, _WEIGHT_COLUMN]) - receipt = { - "operation": RAKE_TO_VENDORED_FACTS_KIND, - "columns": list(columns), - "scope": scope, - "iterations": int(iterations), - "weighted": weights is not None, - "households_in_scope": int(in_scope.sum()), - "weighted_households_in_scope": float(weight_values[in_scope].sum()), - "quintile_edges": quintile_edges, - "cells": [cell.receipt for cell in cells], - "fits": cell_receipts, - "joint_fits": joint_receipts, - "skipped_cells": skipped_cells, - } - return raked, receipt - - -def _rake_joint( - frame: pd.DataFrame, - cell: FactCell, - population: np.ndarray, - weights: np.ndarray, - columns: list[str], -) -> tuple[pd.DataFrame, dict[str, Any]]: - if cell.allocation != ALLOCATION_UNIFORM: - raise ValueError(f"joint cell {cell.label!r} must allocate uniformly.") - values = { - column: pd.to_numeric(frame[column], errors="coerce") - .fillna(0.0) - .to_numpy(dtype=float) - for column in columns - } - before = { - column: float(np.dot(values[column][population], weights[population])) - for column in columns - } - current = sum(before.values()) - if current <= 0: - raise ValueError( - f"joint rake cell {cell.label!r} carries GBP {cell.value:,.0f} but the " - f"columns {columns} sum to zero in scope." - ) - factor = cell.value / current - result = frame.copy() - for column in columns: - scaled = values[column].copy() - scaled[population] *= factor - result[column] = scaled - return result, { - "cell": cell.label, - "label": cell.label, - "columns": list(columns), - "target_total": cell.value, - "weighted_households_in_scope": float(weights[population].sum()), - "weighted_total_before": before, - "factor": factor, - "weighted_total_after": { - column: float( - np.dot( - result[column].to_numpy(dtype=float)[population], - weights[population], - ) - ) - for column in columns - }, - } 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 b2946e6bf..3502946bf 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 @@ -67,8 +67,8 @@ def uk_stage_health_gate( return _bus_travel_facts_gate(stage, evidence, parameters) if check == "bus_pricing": return _bus_pricing_gate(stage, evidence, parameters) - if check == "fact_rake": - return _fact_rake_gate(stage, evidence, parameters) + if check == "bus_support_pricing": + return _bus_support_pricing_gate(stage, evidence, parameters) return GateResult( name="stage_health", passed=False, @@ -1521,100 +1521,107 @@ def _close(observed: object, value: float) -> bool: ) -def _fact_rake_gate( +def _bus_support_pricing_gate( stage: str, evidence: Mapping[str, object], parameters: Mapping[str, object], ) -> GateResult: - """A declared rake to vendored facts hit every published cell it declares. - - Fact checks on a stage's ``rake_to_vendored_facts`` receipt (the ETB - bus-support rake, microcosm#930 C7): every cell's published value is - recomputed from the vendored rows through the stage's own declaration - (never taken from the receipt) and must equal the receipt's; each cell's - design-weighted total after the rake must equal its published value to - ``maximum_relative_deviation`` (a joint cell over the sum of its columns); - a skipped cell fails closed. The receipt key is ``receipt_key`` - (``bus_support_rake`` for the ETB stage). + """The ETB bus-support pricing used the published components per boarding. + + Fact checks on the ``bus_support_pricing`` receipt (microcosm#930): every + declared support area's reimbursement, net support, boardings and + concessionary boardings, and the per-boarding rates derived from them, + are recomputed here from the vendored rows through the stage's own + declaration (never taken from the receipt) and must equal the receipt's + to ``maximum_relative_deviation``; the raw-draw regions must be the + declared ones and the receipt must state that the pricing was applied on + the chain's raw draw. The priced support against the published net + support is reported, not fenced: the calibration targets act on it. """ from microcosm.build.country_spec import load_country_spec - from microcosm.build.uk_runtime.fact_raking import rake_operations, resolve_cells + from microcosm.build.uk_runtime.bus_support_pricing import ( + bus_support_factors, + bus_support_pricing_operation, + ) + from microcosm.build.uk_runtime.etb_services import ( + UK_ETB_SERVICES_VENDORED_RESOURCES, + ) - check = "fact_rake" - key = str(parameters.get("receipt_key") or "") - if not key: - raise ValueError(f"{stage}: fact_rake declares no receipt_key.") - receipt = _mapping(evidence.get(key), label=f"{stage}.{key}") + check = "bus_support_pricing" + receipt = _mapping( + evidence.get("bus_support_pricing"), label=f"{stage}.bus_support_pricing" + ) tolerance = _finite_number( parameters.get("maximum_relative_deviation"), label=f"{stage}.maximum_relative_deviation", ) - allowed = tuple(str(r) for r in parameters.get("allowed_resources", ())) - if not allowed: - raise ValueError(f"{stage}: fact_rake declares no allowed_resources.") - spec_stage = load_country_spec("uk").sources.stage_map()[stage] - operations = rake_operations(spec_stage) - if len(operations) != 1: - raise ValueError( - f"{stage}: fact_rake expects one rake_to_vendored_facts operation, " - f"found {len(operations)}." - ) - cells = { - cell.label: cell - for cell in resolve_cells(operations[0], allowed_resources=allowed) - } + declared = bus_support_pricing_operation( + load_country_spec("uk").sources.stage_map()[stage] + ) + if declared is None: + raise ValueError(f"{stage}: declares no price_bus_support operation.") + factors = bus_support_factors( + declared, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + ) failures: list[str] = [] details: dict[str, object] = { - "receipt_key": key, "maximum_relative_deviation": tolerance, - "cells_fact_checked": 0, - "achieved": {}, + "areas_fact_checked": 0, + "priced_over_published": {}, } - skipped = receipt.get("skipped_cells") or () - if skipped: + if receipt.get("applied") is not True or receipt.get("chain_conditioned_on") != ( + "raw_draw" + ): failures.append( - f"{stage}: {len(skipped)} rake cell(s) were skipped: {skipped!r}." + f"{stage}: the receipt does not state an applied pricing on the raw draw." ) - recorded_cells = { - str(c.get("label")): c - for c in receipt.get("cells", ()) - if isinstance(c, Mapping) - } - fits = [f for f in receipt.get("fits", ()) if isinstance(f, Mapping)] - joint_fits = [f for f in receipt.get("joint_fits", ()) if isinstance(f, Mapping)] - for label, cell in cells.items(): - recorded = recorded_cells.get(label) - if recorded is None: - failures.append(f"{stage}: the receipt carries no cell {label!r}.") + declared_raw = sorted(str(r) for r in declared.get("raw_draw_regions", ())) + if sorted(str(r) for r in receipt.get("raw_draw_regions", ())) != declared_raw: + failures.append( + f"{stage}: raw-draw regions {receipt.get('raw_draw_regions')!r} are not " + f"the declared {declared_raw}." + ) + recorded = _mapping( + receipt.get("by_area"), label=f"{stage}.bus_support_pricing.by_area" + ) + + def _close(observed: object, value: float) -> bool: + return isinstance(observed, int | float) and abs(float(observed) - value) <= ( + tolerance * max(1.0, abs(value)) + ) + + for label, block in factors.items(): + entry = recorded.get(label) + if not isinstance(entry, Mapping): + failures.append(f"{stage}: the receipt prices no support area {label!r}.") continue - value = recorded.get("value") - if not isinstance(value, int | float) or abs(float(value) - cell.value) > ( - 1e-9 * max(1.0, cell.value) + for key in ( + "reimbursement_per_concessionary_boarding", + "other_support_per_boarding", + "published_concessionary_boarding_share", ): - failures.append( - f"{stage}: cell {label!r} was raked to {value!r}, not the vendored " - f"{cell.value}." - ) - if cell.joint_columns: - achieved = sum( - float(sum(dict(f.get("weighted_total_after") or {}).values())) - for f in joint_fits - if str(f.get("label")) == label - ) - else: - achieved = sum( - float(sum(dict(f.get("weighted_total_after") or {}).values())) - for f in fits - if str(f.get("label")) == label - ) - details["achieved"][label] = {"published": cell.value, "achieved": achieved} - details["cells_fact_checked"] = int(details["cells_fact_checked"]) + 1 - if abs(achieved - cell.value) > tolerance * max(1.0, cell.value): - failures.append( - f"{stage}: cell {label!r} totals {achieved:.2f} after the rake against " - f"the published {cell.value:.2f} (tolerance {tolerance})." - ) + if not _close(entry.get(key), float(block[key])): + failures.append( + f"{stage}: {label} {key} {entry.get(key)!r} is not the vendored " + f"{block[key]}." + ) + for key in ("reimbursement", "net_support", "boardings", "concessionary"): + inner = entry.get(key) + observed = inner.get("value") if isinstance(inner, Mapping) else None + if not _close(observed, float(block[key]["value"])): + failures.append( + f"{stage}: {label} {key} {observed!r} is not the vendored " + f"{block[key]['value']}." + ) + ratio = entry.get("priced_over_published") + details["priced_over_published"][label] = ( + float(ratio) if isinstance(ratio, int | float) else None + ) + details["areas_fact_checked"] = int(details["areas_fact_checked"]) + 1 + missing = sorted(set(recorded) - set(factors)) + if missing: + failures.append(f"{stage}: the receipt prices undeclared areas {missing}.") return ( _fail(stage, check, failures, details) if failures diff --git a/packages/microcosm-build/tests/test_country_spec.py b/packages/microcosm-build/tests/test_country_spec.py index 33bddc512..5c47f1ab1 100644 --- a/packages/microcosm-build/tests/test_country_spec.py +++ b/packages/microcosm-build/tests/test_country_spec.py @@ -1359,7 +1359,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", - "uk_stage_etb_services_support_rake", + "uk_stage_etb_services_support_pricing", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", @@ -1459,7 +1459,7 @@ def test_strict_absent_evidence_entries_are_declared(self, manifest) -> None: "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", - "uk_stage_etb_services_support_rake", + "uk_stage_etb_services_support_pricing", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", diff --git a/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py b/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py deleted file mode 100644 index 9ae5e8c69..000000000 --- a/packages/microcosm-build/tests/test_uk_bus_support_per_journey.py +++ /dev/null @@ -1,193 +0,0 @@ -"""The value-side bus-support diagnostic beside the ETB rake (microcosm#930 C7).""" - -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.uk_runtime.bus_fare_pricing import ( - BusFarePricingError, - published_fact, -) -from microcosm.build.uk_runtime.bus_support_per_journey import ( - RECORD_SUPPORT_PER_JOURNEY_KIND, - support_per_journey_diagnostic, -) -from microcosm.build.uk_runtime.etb_services import ( - UK_ETB_SERVICES_VENDORED_RESOURCES, -) - -ENGLAND_OUTSIDE_LONDON = ( - "NORTH_EAST", - "NORTH_WEST", - "YORKSHIRE", - "EAST_MIDLANDS", - "WEST_MIDLANDS", - "EAST_OF_ENGLAND", - "SOUTH_EAST", - "SOUTH_WEST", -) - - -def _declared() -> dict: - stage = load_country_spec("uk").sources.stage_map()["etb_services"] - parameters = next( - dict(op.parameters) - for op in stage.operations - if op.kind == RECORD_SUPPORT_PER_JOURNEY_KIND - ) - assert parameters["support_column"] == "bus_subsidy_spending" - assert [a["label"] for a in parameters["support_areas"]] == [ - "london", - "england_outside_london", - ] - assert parameters["support_areas"][1]["regions"] == list(ENGLAND_OUTSIDE_LONDON) - return parameters - - -def _frame() -> tuple[pd.DataFrame, pd.DataFrame, np.ndarray, np.ndarray]: - household = pd.DataFrame( - { - "household_id": [1, 2, 3, 4], - "region": ["LONDON", "SOUTH_EAST", "NORTH_WEST", "WALES"], - } - ) - person = pd.DataFrame( - { - "person_id": [11, 12, 21, 31, 41], - "person_household_id": [1, 1, 2, 3, 4], - "bus_in_london_trips": [100.0, 40.0, 0.0, 10.0, 0.0], - "other_local_bus_trips": [0.0, 10.0, 60.0, 30.0, 50.0], - "bus_pass_eligible": [False, True, True, False, True], - } - ) - weights = np.array([2.0, 3.0, 4.0, 5.0]) - raked = np.array([120.0, 80.0, 90.0, 70.0]) - return person, household, weights, raked - - -def test_value_side_support_recomputes_from_the_vendored_rows() -> None: - parameters = _declared() - person, household, weights, raked = _frame() - receipt = support_per_journey_diagnostic( - parameters, - person=person, - household=household, - household_weights=weights, - raked_support=raked, - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - ) - assert receipt["operation"] == RECORD_SUPPORT_PER_JOURNEY_KIND - assert receipt["applied"] is False - assert receipt["support_column"] == "bus_subsidy_spending" - k_london = receipt["boardings_per_trip"]["bus_in_london"] - k_england = receipt["boardings_per_trip"]["england_outside_london"] - assert k_london > 0 and k_england > 0 - - area = dict(parameters["support_areas"][1]) - fiscal_start = parameters["fiscal_start"] - reimbursement, _ = published_fact( - area["reimbursement"], - unit="gbp", - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - fiscal_start=fiscal_start, - ) - net_support, _ = published_fact( - area["net_support"], - unit="gbp", - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - fiscal_start=fiscal_start, - ) - boardings, _ = published_fact( - area["boardings"], - unit="count", - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - fiscal_start=fiscal_start, - ) - concessionary, _ = published_fact( - area["concessionary"], - unit="count", - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - fiscal_start=fiscal_start, - ) - assert 0 < reimbursement < net_support - assert 0 < concessionary < boardings - england = receipt["by_area"]["england_outside_london"] - # Households 2 (SOUTH_EAST, weight 3) and 3 (NORTH_WEST, weight 4): - # person 21 (eligible) 60 other trips; person 31 10 London + 30 other trips. - all_boardings = 3.0 * 60.0 * k_england + 4.0 * (10.0 * k_london + 30.0 * k_england) - eligible_boardings = 3.0 * 60.0 * k_england - assert england["frame_boardings"] == pytest.approx(all_boardings) - assert england["frame_eligible_boardings"] == pytest.approx(eligible_boardings) - assert england["frame_eligible_boarding_share"] == pytest.approx( - eligible_boardings / all_boardings - ) - assert england["published_concessionary_boarding_share"] == pytest.approx( - concessionary / boardings - ) - assert england["reimbursement_per_concessionary_boarding"] == pytest.approx( - reimbursement / concessionary - ) - assert england["other_support_per_boarding"] == pytest.approx( - (net_support - reimbursement) / boardings - ) - assert england["value_side_support"] == pytest.approx( - reimbursement / concessionary * eligible_boardings - + (net_support - reimbursement) / boardings * all_boardings - ) - assert england["raked_support"] == pytest.approx(3.0 * 80.0 + 4.0 * 90.0) - assert england["value_side_over_raked"] == pytest.approx( - england["value_side_support"] / england["raked_support"] - ) - assert england["households"] == 2 and england["persons"] == 2 - london = receipt["by_area"]["london"] - assert london["frame_boardings"] == pytest.approx( - 2.0 * (100.0 * k_london + 40.0 * k_london + 10.0 * k_england) - ) - # Person 12 is eligible: 40 London-series and 10 other-local-bus trips. - assert london["frame_eligible_boardings"] == pytest.approx( - 2.0 * (40.0 * k_london + 10.0 * k_england) - ) - assert london["raked_support"] == pytest.approx(2.0 * 120.0) - # Wales is unpriced and outside every support area: recorded nowhere. - assert set(receipt["by_area"]) == {"london", "england_outside_london"} - - -def test_diagnostic_refusals() -> None: - parameters = _declared() - person, household, weights, raked = _frame() - with pytest.raises( - BusFarePricingError, match="nts_bus_travel stage must run first" - ): - support_per_journey_diagnostic( - parameters, - person=person.drop(columns=["bus_pass_eligible"]), - household=household, - household_weights=weights, - raked_support=raked, - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - ) - foreign = dict(parameters) - foreign["support_areas"] = [ - {**dict(parameters["support_areas"][0]), "regions": ["LONDON", "WALES"]} - ] - with pytest.raises(BusFarePricingError, match="pricing areas do not price"): - support_per_journey_diagnostic( - foreign, - person=person, - household=household, - household_weights=weights, - raked_support=raked, - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - ) - with pytest.raises(BusFarePricingError, match="not a record_support_per_journey"): - support_per_journey_diagnostic( - {**parameters, "kind": "price_bus_journeys"}, - person=person, - household=household, - household_weights=weights, - raked_support=raked, - allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, - ) diff --git a/packages/microcosm-build/tests/test_uk_bus_support_pricing.py b/packages/microcosm-build/tests/test_uk_bus_support_pricing.py new file mode 100644 index 000000000..3da730324 --- /dev/null +++ b/packages/microcosm-build/tests/test_uk_bus_support_pricing.py @@ -0,0 +1,219 @@ +"""Bus support priced from journeys at the published support per boarding (microcosm#930).""" + +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.uk_runtime.bus_fare_pricing import BusFarePricingError +from microcosm.build.uk_runtime.bus_support_pricing import ( + PRICE_BUS_SUPPORT_KIND, + bus_support_factors, + bus_support_pricing_operation, + price_bus_support, +) +from microcosm.build.uk_runtime.etb_services import ( + UK_ETB_SERVICES_VENDORED_RESOURCES, +) + +ENGLAND_OUTSIDE_LONDON = ( + "NORTH_EAST", + "NORTH_WEST", + "YORKSHIRE", + "EAST_MIDLANDS", + "WEST_MIDLANDS", + "EAST_OF_ENGLAND", + "SOUTH_EAST", + "SOUTH_WEST", +) + + +def _declared() -> dict: + stage = load_country_spec("uk").sources.stage_map()["etb_services"] + parameters = bus_support_pricing_operation(stage) + assert parameters is not None and parameters["kind"] == PRICE_BUS_SUPPORT_KIND + assert parameters["support_column"] == "bus_subsidy_spending" + assert [a["label"] for a in parameters["support_areas"]] == [ + "london", + "england_outside_london", + "scotland", + ] + assert parameters["raw_draw_regions"] == ["WALES", "NORTHERN_IRELAND"] + assert parameters["support_areas"][1]["regions"] == list(ENGLAND_OUTSIDE_LONDON) + return parameters + + +def _frame() -> tuple[pd.DataFrame, pd.DataFrame, np.ndarray, np.ndarray]: + household = pd.DataFrame( + { + "household_id": [1, 2, 3, 4, 5, 6], + "region": [ + "LONDON", + "SOUTH_EAST", + "NORTH_WEST", + "WALES", + "SCOTLAND", + "NORTHERN_IRELAND", + ], + } + ) + person = pd.DataFrame( + { + "person_id": [11, 12, 21, 31, 41, 51, 52, 61], + "person_household_id": [1, 1, 2, 3, 4, 5, 5, 6], + "bus_in_london_trips": [100.0, 40.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0], + "other_local_bus_trips": [0.0, 10.0, 60.0, 30.0, 50.0, 20.0, 80.0, 30.0], + "bus_pass_eligible": [False, True, True, False, True, True, False, True], + } + ) + weights = np.array([2.0, 3.0, 4.0, 5.0, 6.0, 7.0]) + raw = np.array([120.0, 80.0, 90.0, 70.0, 60.0, 50.0]) + return person, household, weights, raw + + +def test_factors_recompute_from_the_vendored_rows() -> None: + factors = bus_support_factors( + _declared(), allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + ) + assert set(factors) == {"london", "england_outside_london", "scotland"} + for label, block in factors.items(): + reimbursement = block["reimbursement"]["value"] + net = block["net_support"]["value"] + boardings = block["boardings"]["value"] + concessionary = block["concessionary"]["value"] + assert 0 < reimbursement < net, label + assert 0 < concessionary < boardings, label + assert block["reimbursement_per_concessionary_boarding"] == pytest.approx( + reimbursement / concessionary + ) + assert block["other_support_per_boarding"] == pytest.approx( + (net - reimbursement) / boardings + ) + assert block["published_concessionary_boarding_share"] == pytest.approx( + concessionary / boardings + ) + # Scotland's components come from the Scottish Transport Statistics rows: + # concessionary fares inside all government support. + scotland = factors["scotland"] + assert scotland["net_support"]["value"] == pytest.approx(499_000_000.0) + assert scotland["reimbursement"]["value"] == pytest.approx(392_000_000.0) + assert scotland["regions"] == ["SCOTLAND"] + + +def test_support_is_priced_per_area_and_raw_elsewhere() -> None: + parameters = _declared() + person, household, weights, raw = _frame() + values, priced, receipt = price_bus_support( + parameters, + person=person, + household=household, + household_weights=weights, + raw_support=raw, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + factors = bus_support_factors( + parameters, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + ) + k_london = receipt["boardings_per_trip"]["bus_in_london"] + k_england = receipt["boardings_per_trip"]["england_outside_london"] + k_scotland = receipt["boardings_per_trip"]["scotland"] + eol = factors["england_outside_london"] + lon = factors["london"] + sco = factors["scotland"] + # Household 1 (London): person 11 not eligible, 100 London trips; person 12 + # eligible, 40 London + 10 other trips (other trips price at the + # England-outside-London translation for London residents). + b11 = 100.0 * k_london + b12 = 40.0 * k_london + 10.0 * k_england + expected_1 = ( + lon["other_support_per_boarding"] * (b11 + b12) + + lon["reimbursement_per_concessionary_boarding"] * b12 + ) + assert values[0] == pytest.approx(expected_1) + # Household 2 (South East): person 21 eligible, 60 other trips. + b21 = 60.0 * k_england + assert values[1] == pytest.approx( + ( + eol["other_support_per_boarding"] + + eol["reimbursement_per_concessionary_boarding"] + ) + * b21 + ) + # Household 3 (North West): person 31 not eligible, 10 London + 30 other. + b31 = 10.0 * k_london + 30.0 * k_england + assert values[2] == pytest.approx(eol["other_support_per_boarding"] * b31) + # Household 5 (Scotland): person 51 eligible 20 trips, person 52 not, 80. + b51, b52 = 20.0 * k_scotland, 80.0 * k_scotland + assert values[4] == pytest.approx( + sco["other_support_per_boarding"] * (b51 + b52) + + sco["reimbursement_per_concessionary_boarding"] * b51 + ) + # Wales and Northern Ireland keep the raw draw. + assert values[3] == 70.0 and values[5] == 50.0 + assert priced.tolist() == [True, True, True, False, True, False] + assert receipt["applied"] is True + assert receipt["chain_conditioned_on"] == "raw_draw" + assert receipt["raw_draw_regions"] == ["NORTHERN_IRELAND", "WALES"] + assert receipt["households_priced"] == 4 and receipt["households_raw_draw"] == 2 + assert receipt["raw_draw_weighted_support"] == { + "NORTHERN_IRELAND": pytest.approx(7.0 * 50.0), + "WALES": pytest.approx(5.0 * 70.0), + } + england = receipt["by_area"]["england_outside_london"] + assert england["frame_boardings"] == pytest.approx(3.0 * b21 + 4.0 * b31) + assert england["frame_eligible_boardings"] == pytest.approx(3.0 * b21) + assert england["weighted_support_before"] == pytest.approx(3.0 * 80.0 + 4.0 * 90.0) + assert england["weighted_support_after"] == pytest.approx( + 3.0 * values[1] + 4.0 * values[2] + ) + assert england["priced_over_published"] == pytest.approx( + england["weighted_support_after"] / eol["net_support"]["value"] + ) + assert receipt["weighted_support_after"] == pytest.approx( + float(np.dot(values, weights)) + ) + + +def test_pricing_refusals() -> None: + parameters = _declared() + person, household, weights, raw = _frame() + with pytest.raises( + BusFarePricingError, match="nts_bus_travel stage must run first" + ): + price_bus_support( + parameters, + person=person.drop(columns=["bus_pass_eligible"]), + household=household, + household_weights=weights, + raw_support=raw, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + with pytest.raises(BusFarePricingError, match="neither in a support area"): + price_bus_support( + {**parameters, "raw_draw_regions": ["WALES"]}, + person=person, + household=household, + household_weights=weights, + raw_support=raw, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + with pytest.raises(BusFarePricingError, match="both priced and declared"): + price_bus_support( + {**parameters, "raw_draw_regions": ["WALES", "NORTHERN_IRELAND", "LONDON"]}, + person=person, + household=household, + household_weights=weights, + raw_support=raw, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) + with pytest.raises(BusFarePricingError, match="not a price_bus_support"): + price_bus_support( + {**parameters, "kind": "price_bus_journeys"}, + person=person, + household=household, + household_weights=weights, + raw_support=raw, + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, + ) diff --git a/packages/microcosm-build/tests/test_uk_fact_raking.py b/packages/microcosm-build/tests/test_uk_fact_raking.py deleted file mode 100644 index 4a5894d1a..000000000 --- a/packages/microcosm-build/tests/test_uk_fact_raking.py +++ /dev/null @@ -1,374 +0,0 @@ -"""Rakes of imputed columns to vendored publisher facts (#890 D).""" - -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.uk_runtime.etb_services import ( - UK_ETB_SERVICES_VENDORED_RESOURCES, - etb_bus_support_rake, -) -from microcosm.build.uk_runtime.fact_raking import ( - FactCell, - person_income_quintiles, - rake_operations, - rake_to_facts, - resolve_cells, -) -from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows - -OUTSIDE_LONDON = ( - "NORTH_EAST", - "NORTH_WEST", - "YORKSHIRE", - "EAST_MIDLANDS", - "WEST_MIDLANDS", - "EAST_OF_ENGLAND", - "SOUTH_EAST", - "SOUTH_WEST", -) - - -def _stage(name: str): - return load_country_spec("uk").sources.stage_map()[name] - - -def _fact(resource: str, **criteria) -> float: - rows = vendored_rows(resource, **criteria) - assert rows, criteria - return float(sum(row["value"] for row in rows)) - - -def test_etb_support_cells_cover_every_nation_with_the_ni_joint_cell() -> None: - (operation,) = rake_operations(_stage("etb_services")) - assert operation["columns"] == ["bus_subsidy_spending"] - assert operation["scope"] == "all" - - cells = { - cell.label: cell - for cell in resolve_cells( - operation, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES - ) - } - assert set(cells) == { - "london", - "england_outside_london", - "scotland", - "wales", - "northern_ireland", - } - assert cells["london"].value == 1_130_214_000.0 - assert cells["england_outside_london"].value == pytest.approx(1_894_690_320.84) - assert cells["scotland"].value == 499_000_000.0 - assert cells["wales"].value == pytest.approx(62_443_460 + 69_046_510) - assert cells["northern_ireland"].value == pytest.approx(61_800_000 + 49_900_000) - assert cells["northern_ireland"].joint_columns == ( - "bus_subsidy_spending", - "rail_subsidy_spending", - ) - assert all(cell.allocation == "uniform" for cell in cells.values()) - covered = {region for cell in cells.values() for region in cell.regions} - assert covered == { - "LONDON", - *OUTSIDE_LONDON, - "SCOTLAND", - "WALES", - "NORTHERN_IRELAND", - } - - -def test_resolve_cells_refuses_resources_the_stage_does_not_declare() -> None: - (operation,) = rake_operations(_stage("etb_services")) - with pytest.raises(ValueError, match="does not declare"): - resolve_cells(operation, allowed_resources=("road_fuel_anchors.json",)) - import copy - - duplicated = copy.deepcopy(operation) - duplicated["cells"][1]["regions"].append("LONDON") - with pytest.raises(ValueError, match="repeats regions"): - resolve_cells(duplicated, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES) - wrong_period = copy.deepcopy(operation) - wrong_period["cells"][0]["selector"]["fiscal_start"] = "1999-04-01" - with pytest.raises(ValueError, match="expected exactly one row"): - resolve_cells( - wrong_period, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES - ) - - -def test_person_income_quintiles_rank_people_not_households() -> None: - income = np.array([10.0, 20.0, 30.0, 40.0, 50.0, 60.0]) - persons = np.array([1.0, 1.0, 1.0, 1.0, 1.0, 100.0]) - weights = np.ones(6) - labels, edges = person_income_quintiles( - income, persons, weights, mask=np.array([True] * 5 + [False]) - ) - assert labels.tolist() == ["lowest", "second", "third", "fourth", "highest", ""] - assert edges == [20.0, 30.0, 40.0, 50.0] - # The last household's 100 persons dominate once it is in the mask: it - # spans every quintile boundary, so all four edges sit at its income and - # the five one-person households all fall in the lowest quintile. - labels, edges = person_income_quintiles( - income, persons, weights, mask=np.ones(6, bool) - ) - assert edges == [60.0, 60.0, 60.0, 60.0] - assert labels.tolist()[:5] == ["lowest"] * 5 - - -def _synthetic(n: int = 600, seed: int = 5) -> tuple[pd.DataFrame, dict]: - rng = np.random.default_rng(seed) - regions = rng.choice( - ["LONDON", "SOUTH_EAST", "NORTH_WEST", "SCOTLAND", "WALES", "NORTHERN_IRELAND"], - n, - ) - frame = pd.DataFrame( - { - "bus_fare_spending": rng.uniform(0.0, 500.0, n), - "bus_subsidy_spending": rng.uniform(10.0, 300.0, n), - "rail_subsidy_spending": rng.uniform(10.0, 300.0, n), - } - ) - frame.loc[rng.random(n) < 0.3, "bus_fare_spending"] = 0.0 - inputs = { - "region": regions, - "weights": rng.uniform(0.5, 3.0, n), - "users": rng.random(n) < 0.6, - "income": rng.uniform(5e3, 1e5, n), - "persons": rng.integers(1, 5, n).astype(float), - } - return frame, inputs - - -def test_users_only_rake_hits_each_cell_total_and_leaves_the_rest() -> None: - frame, inputs = _synthetic() - quintile_trips = { - "lowest": 40.0, - "second": 30.0, - "third": 20.0, - "fourth": 15.0, - "highest": 10.0, - } - cells = [ - FactCell( - "london", - ("LONDON",), - 1_000_000.0, - "income_quintile_trips", - quintile_trips, - (), - {}, - ), - FactCell( - "outside", - ("SOUTH_EAST", "NORTH_WEST"), - 2_000_000.0, - "income_quintile_trips", - quintile_trips, - (), - {}, - ), - FactCell("scotland", ("SCOTLAND",), 300_000.0, "uniform", None, (), {}), - ] - raked, receipt = rake_to_facts( - frame, - columns=["bus_fare_spending"], - cells=cells, - region=inputs["region"], - weights=inputs["weights"], - scope="users_only", - users=inputs["users"], - quintile_income=inputs["income"], - household_persons=inputs["persons"], - ) - fares = raked["bus_fare_spending"].to_numpy() - w = inputs["weights"] - region = inputs["region"] - users = inputs["users"] - - def total(mask): - return float(np.dot(fares[mask], w[mask])) - - assert total((region == "LONDON") & users) == pytest.approx(1_000_000.0) - assert total( - np.isin(region, ["SOUTH_EAST", "NORTH_WEST"]) & users - ) == pytest.approx(2_000_000.0) - assert total((region == "SCOTLAND") & users) == pytest.approx(300_000.0) - # Non-users are outside the rake scope and Wales names no cell. - assert (fares[~users] == frame["bus_fare_spending"].to_numpy()[~users]).all() - assert ( - fares[region == "WALES"] - == frame["bus_fare_spending"].to_numpy()[region == "WALES"] - ).all() - assert (raked["bus_subsidy_spending"] == frame["bus_subsidy_spending"]).all() - # Within London the quintile shares follow persons x trips per person. - london_fits = [fit for fit in receipt["fits"] if fit["label"] == "london"] - assert len(london_fits) == 5 - assert sum(fit["share"] for fit in london_fits) == pytest.approx(1.0) - assert all( - fit["weighted_total_after"]["bus_fare_spending"] - == pytest.approx(fit["target_total"]) - for fit in receipt["fits"] - ) - assert len(receipt["quintile_edges"]) == 4 - assert receipt["scope"] == "users_only" - assert receipt["joint_fits"] == [] - - -def test_joint_cell_scales_both_columns_by_one_factor() -> None: - frame, inputs = _synthetic() - cells = [ - FactCell( - "northern_ireland", - ("NORTHERN_IRELAND",), - 50_000.0, - "uniform", - None, - ("bus_subsidy_spending", "rail_subsidy_spending"), - {}, - ), - FactCell("wales", ("WALES",), 40_000.0, "uniform", None, (), {}), - ] - raked, receipt = rake_to_facts( - frame, - columns=["bus_subsidy_spending"], - cells=cells, - region=inputs["region"], - weights=inputs["weights"], - scope="all", - ) - ni = inputs["region"] == "NORTHERN_IRELAND" - w = inputs["weights"] - joint_total = float( - np.dot(raked["bus_subsidy_spending"].to_numpy()[ni], w[ni]) - + np.dot(raked["rail_subsidy_spending"].to_numpy()[ni], w[ni]) - ) - assert joint_total == pytest.approx(50_000.0) - ratio_bus = ( - raked["bus_subsidy_spending"].to_numpy()[ni] - / frame["bus_subsidy_spending"].to_numpy()[ni] - ) - ratio_rail = ( - raked["rail_subsidy_spending"].to_numpy()[ni] - / frame["rail_subsidy_spending"].to_numpy()[ni] - ) - assert np.allclose(ratio_bus, ratio_bus[0]) and np.allclose( - ratio_rail, ratio_bus[0] - ) - (joint,) = receipt["joint_fits"] - assert joint["factor"] == pytest.approx(ratio_bus[0]) - wales = inputs["region"] == "WALES" - assert float(np.dot(raked["bus_subsidy_spending"].to_numpy()[wales], w[wales])) == ( - pytest.approx(40_000.0) - ) - # Rail outside Northern Ireland is untouched by a joint cell elsewhere. - assert ( - raked["rail_subsidy_spending"][~ni] == frame["rail_subsidy_spending"][~ni] - ).all() - - -def test_rake_skips_a_cell_whose_regions_are_absent_from_the_frame() -> None: - frame, inputs = _synthetic() - cells = [ - FactCell("london", ("LONDON",), 1_000.0, "uniform", None, (), {}), - FactCell("atlantis", ("ATLANTIS",), 5_000.0, "uniform", None, (), {}), - FactCell( - "joint_atlantis", - ("LEMURIA",), - 7_000.0, - "uniform", - None, - ("bus_subsidy_spending", "rail_subsidy_spending"), - {}, - ), - ] - raked, receipt = rake_to_facts( - frame, - columns=["bus_fare_spending"], - cells=cells, - region=inputs["region"], - weights=inputs["weights"], - scope="all", - ) - london = inputs["region"] == "LONDON" - assert float( - np.dot(raked["bus_fare_spending"].to_numpy()[london], inputs["weights"][london]) - ) == pytest.approx(1_000.0) - assert [cell["cell"] for cell in receipt["skipped_cells"]] == [ - "atlantis", - "joint_atlantis", - ] - assert ( - receipt["skipped_cells"][0]["reason"] == "no households in the cell's regions" - ) - assert receipt["joint_fits"] == [] - - -def test_rake_refuses_a_cell_with_published_mass_but_nobody_in_scope() -> None: - frame, inputs = _synthetic() - cells = [FactCell("london", ("LONDON",), 1_000.0, "uniform", None, (), {})] - with pytest.raises(ValueError, match="no households in scope"): - rake_to_facts( - frame, - columns=["bus_fare_spending"], - cells=cells, - region=inputs["region"], - weights=inputs["weights"], - scope="users_only", - users=np.zeros(len(frame), dtype=bool), - ) - zeroed = frame.copy() - zeroed["bus_fare_spending"] = 0.0 - with pytest.raises(ValueError, match="current mean is zero"): - rake_to_facts( - zeroed, - columns=["bus_fare_spending"], - cells=cells, - region=inputs["region"], - weights=inputs["weights"], - scope="all", - ) - with pytest.raises(ValueError, match="unknown rake scope"): - rake_to_facts( - frame, - columns=["bus_fare_spending"], - cells=cells, - region=inputs["region"], - weights=None, - scope="some", - ) - - -def test_etb_stage_helper_applies_the_declared_support_rake() -> None: - frame, inputs = _synthetic(n=2000, seed=9) - rng = np.random.default_rng(1) - regions = rng.choice( - ["LONDON", *OUTSIDE_LONDON, "SCOTLAND", "WALES", "NORTHERN_IRELAND"], len(frame) - ) - raked, receipt = etb_bus_support_rake( - _stage("etb_services"), - frame, - household=pd.DataFrame({"region": regions}), - weights=inputs["weights"], - ) - assert receipt is not None - assert receipt["scope"] == "all" - w = inputs["weights"] - london = regions == "LONDON" - assert float( - np.dot(raked["bus_subsidy_spending"].to_numpy()[london], w[london]) - ) == (pytest.approx(1_130_214_000.0)) - ni = regions == "NORTHERN_IRELAND" - assert float( - np.dot(raked["bus_subsidy_spending"].to_numpy()[ni], w[ni]) - + np.dot(raked["rail_subsidy_spending"].to_numpy()[ni], w[ni]) - ) == pytest.approx(111_700_000.0) - - class Stage: - operations = () - - untouched, none = etb_bus_support_rake( - Stage(), frame, household=pd.DataFrame({"region": regions}), weights=w - ) - assert none is None and untouched is frame diff --git a/packages/microcosm-build/tests/test_uk_source_stages.py b/packages/microcosm-build/tests/test_uk_source_stages.py index ab5184a20..0b954964d 100644 --- a/packages/microcosm-build/tests/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/test_uk_source_stages.py @@ -676,8 +676,7 @@ def test_e3_operation_kinds_are_declared_in_order(self) -> None: "materialize_rules_engine_predictors", "fit_weighted_qrf_chain", "support_clip", - "rake_to_vendored_facts", - "record_support_per_journey", + "price_bus_support", "compute_ratio", "allocate_per_capita_from_cell_table", "record_mass_conservation_receipt", diff --git a/packages/microcosm-build/tests/test_uk_stage_health.py b/packages/microcosm-build/tests/test_uk_stage_health.py index 02596a764..5765874cc 100644 --- a/packages/microcosm-build/tests/test_uk_stage_health.py +++ b/packages/microcosm-build/tests/test_uk_stage_health.py @@ -930,115 +930,92 @@ def run(ev): run(None) -def test_fact_rake_gate_fact_checks_the_etb_support_rake_receipt() -> None: - """The ETB bus-support rake receipt is fenced at stage time (microcosm#930 C7).""" +def test_bus_support_pricing_gate_recomputes_the_factors_from_the_vendored_rows() -> ( + None +): + """The ETB bus-support pricing receipt is fenced at stage time (microcosm#930).""" import copy import pandas as pd from microcosm.build.country_spec import load_country_spec + from microcosm.build.uk_runtime.bus_support_pricing import ( + bus_support_pricing_operation, + price_bus_support, + ) from microcosm.build.uk_runtime.etb_services import ( UK_ETB_SERVICES_VENDORED_RESOURCES, ) - from microcosm.build.uk_runtime.fact_raking import ( - rake_operations, - rake_to_facts, - resolve_cells, - ) - parameters = _gate_parameters("uk_stage_etb_services_support_rake") - assert parameters["check"] == "fact_rake" - assert parameters["receipt_key"] == "bus_support_rake" - assert set(parameters["allowed_resources"]) == set( - UK_ETB_SERVICES_VENDORED_RESOURCES + parameters = _gate_parameters("uk_stage_etb_services_support_pricing") + assert parameters["check"] == "bus_support_pricing" + declared = bus_support_pricing_operation( + load_country_spec("uk").sources.stage_map()["etb_services"] ) - stage = load_country_spec("uk").sources.stage_map()["etb_services"] - (declaration,) = rake_operations(stage) - cells = resolve_cells( - declaration, allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES + household = pd.DataFrame( + { + "household_id": [1, 2, 3, 4, 5], + "region": ["LONDON", "SOUTH_EAST", "WALES", "SCOTLAND", "NORTHERN_IRELAND"], + } ) - regions = [ - "LONDON", - "NORTH_EAST", - "NORTH_WEST", - "YORKSHIRE", - "EAST_MIDLANDS", - "WEST_MIDLANDS", - "EAST_OF_ENGLAND", - "SOUTH_EAST", - "SOUTH_WEST", - "SCOTLAND", - "WALES", - "NORTHERN_IRELAND", - ] - draws = pd.DataFrame( + person = pd.DataFrame( { - "bus_subsidy_spending": np.linspace(100.0, 320.0, len(regions)), - "rail_subsidy_spending": np.linspace(50.0, 160.0, len(regions)), + "person_id": [11, 12, 21, 31, 41, 51], + "person_household_id": [1, 1, 2, 3, 4, 5], + "bus_in_london_trips": [100.0, 50.0, 0.0, 0.0, 0.0, 0.0], + "other_local_bus_trips": [0.0, 10.0, 40.0, 30.0, 20.0, 25.0], + "bus_pass_eligible": [False, True, False, False, True, True], } ) - _, receipt = rake_to_facts( - draws, - columns=["bus_subsidy_spending"], - cells=cells, - region=regions, - weights=np.linspace(1000.0, 12000.0, len(regions)), - scope=str(declaration["scope"]), - iterations=int(declaration.get("iterations", 1)), + _, _, receipt = price_bus_support( + declared, + person=person, + household=household, + household_weights=np.array([1.0, 2.0, 3.0, 4.0, 5.0]), + raw_support=np.array([50.0, 60.0, 70.0, 80.0, 90.0]), + allowed_resources=UK_ETB_SERVICES_VENDORED_RESOURCES, ) - assert receipt["skipped_cells"] == [] - def run(ev, params=parameters): + def run(ev): return uk_stage_health_gate( - evidence={"stage": "etb_services", "bus_support_rake": ev}, + evidence={"stage": "etb_services", "bus_support_pricing": ev}, stage="etb_services", - check="fact_rake", - parameters=params, + check="bus_support_pricing", + parameters=parameters, ) passed = run(receipt) assert passed.passed, passed.failures - assert passed.details["cells_fact_checked"] == len(cells) == 5 - assert set(passed.details["achieved"]) == { + assert passed.details["areas_fact_checked"] == 3 + assert set(passed.details["priced_over_published"]) == { "london", "england_outside_london", "scotland", - "wales", - "northern_ireland", } - for label, block in passed.details["achieved"].items(): - assert block["achieved"] == pytest.approx(block["published"], rel=1e-9), label - tampered = copy.deepcopy(receipt) - tampered["cells"][0]["value"] *= 1.01 - result = run(tampered) - assert not result.passed and any("not the vendored" in f for f in result.failures) tampered = copy.deepcopy(receipt) - for fit in tampered["fits"]: - if fit["label"] == "scotland": - fit["weighted_total_after"]["bus_subsidy_spending"] *= 1.01 + tampered["by_area"]["scotland"]["other_support_per_boarding"] *= 1.01 result = run(tampered) assert not result.passed and any( - "'scotland' totals" in f for f in result.failures + "scotland other_support_per_boarding" in f for f in result.failures ), result.failures tampered = copy.deepcopy(receipt) - for fit in tampered["joint_fits"]: - fit["weighted_total_after"]["rail_subsidy_spending"] *= 1.01 + tampered["by_area"]["london"]["net_support"]["value"] *= 1.01 result = run(tampered) - assert not result.passed and any( - "'northern_ireland' totals" in f for f in result.failures - ), result.failures + assert not result.passed and any("london net_support" in f for f in result.failures) + tampered = copy.deepcopy(receipt) + tampered["raw_draw_regions"] = ["WALES"] + result = run(tampered) + assert not result.passed and any("raw-draw regions" in f for f in result.failures) tampered = copy.deepcopy(receipt) - tampered["skipped_cells"] = [{"cell": "wales", "reason": "no households"}] + tampered["applied"] = False result = run(tampered) - assert not result.passed and any("were skipped" in f for f in result.failures) + assert not result.passed and any("applied pricing" in f for f in result.failures) tampered = copy.deepcopy(receipt) - tampered["cells"] = [c for c in tampered["cells"] if c["label"] != "wales"] + del tampered["by_area"]["scotland"] result = run(tampered) assert not result.passed and any( - "carries no cell 'wales'" in f for f in result.failures + "no support area 'scotland'" in f for f in result.failures ) - with pytest.raises(ValueError, match="declares no receipt_key"): - run(receipt, {**parameters, "receipt_key": ""}) - with pytest.raises(ValueError, match="bus_support_rake must be an object"): + with pytest.raises(ValueError, match="bus_support_pricing must be an object"): run(None) diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index eb7b2c98b..79e26e7f6 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -475,7 +475,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_stage_lcfs_consumption_bus_pricing": ("stage_health", "transferred"), "uk_stage_etb_vat_support": ("stage_health", "transferred"), "uk_stage_etb_services_support": ("stage_health", "transferred"), - "uk_stage_etb_services_support_rake": ("stage_health", "transferred"), + "uk_stage_etb_services_support_pricing": ("stage_health", "transferred"), "uk_stage_frs_hmrc_spine_leaves_signal": ( "stage_health", "transferred", @@ -573,7 +573,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_etb_vat_support", "uk_stage_etb_services_support", - "uk_stage_etb_services_support_rake", + "uk_stage_etb_services_support_pricing", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_spi_support_channel_mass", "uk_stage_hmrc_spi_income_spine_identity", @@ -729,7 +729,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "uk_stage_cgt_incidence_anchor_composition", "uk_stage_cgt_incidence_clone_mass", "uk_stage_etb_services_support", - "uk_stage_etb_services_support_rake", + "uk_stage_etb_services_support_pricing", "uk_stage_etb_vat_support", "uk_stage_frs_hmrc_spine_leaves_signal", "uk_stage_frs_relationships_composition", diff --git a/packages/microcosm-data/tests/test_contract.py b/packages/microcosm-data/tests/test_contract.py index 98c237504..69bdd6c15 100644 --- a/packages/microcosm-data/tests/test_contract.py +++ b/packages/microcosm-data/tests/test_contract.py @@ -161,7 +161,7 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "uk_stage_nts_bus_travel_facts": ("stage_health", "transferred", None), "uk_stage_etb_vat_support": ("stage_health", "transferred", None), "uk_stage_etb_services_support": ("stage_health", "transferred", None), - "uk_stage_etb_services_support_rake": ("stage_health", "transferred", None), + "uk_stage_etb_services_support_pricing": ("stage_health", "transferred", None), "uk_stage_frs_hmrc_spine_leaves_signal": ( "stage_health", "transferred", @@ -1187,7 +1187,7 @@ def _gate_battery_payload( "uk_stage_nts_bus_travel_facts": "nts_bus_travel", "uk_stage_etb_vat_support": "etb_vat", "uk_stage_etb_services_support": "etb_services", - "uk_stage_etb_services_support_rake": "etb_services", + "uk_stage_etb_services_support_pricing": "etb_services", "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", 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 6c4148fa5..89f82d4d0 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 @@ -360,7 +360,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 support rake levels away in every nation and which therefore only positions the donor before the QRF), rakes bus support so each area's design-weighted total equals the FY2024-25 published net support (DfT BUS05bi for London and England outside London, Scottish Transport Statistics all government support, the StatsWales local-authority gross expenditure on concessionary fares plus support to operators for Wales, and for Northern Ireland the NITHC accounts' PSO plus concessionary compensation bound jointly on bus plus rail support since the accounts carry no split; microcosm#890 D), with the raked column exempt from the support clip, 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", "operations": [ { "annualization_weeks": 52, @@ -434,122 +434,14 @@ "weights": "explicit" }, { - "exempt": [ - "bus_subsidy_spending" - ], "kind": "support_clip", "range": "donor_realized" }, { - "cells": [ - { - "allocation": "uniform", - "label": "london", - "regions": [ - "LONDON" - ], - "resource": "dft_bus_value_anchors.json", - "selector": { - "concept": "dft.local_bus_total_estimated_net_support", - "fiscal_start": "2024-04-01", - "geography_id": "E12000007" - } - }, - { - "allocation": "uniform", - "label": "england_outside_london", - "regions": [ - "NORTH_EAST", - "NORTH_WEST", - "YORKSHIRE", - "EAST_MIDLANDS", - "WEST_MIDLANDS", - "EAST_OF_ENGLAND", - "SOUTH_EAST", - "SOUTH_WEST" - ], - "resource": "dft_bus_value_anchors.json", - "selector": { - "concept": "dft.local_bus_total_estimated_net_support", - "fiscal_start": "2024-04-01", - "geography_id": "dft:england_outside_london" - } - }, - { - "allocation": "uniform", - "label": "scotland", - "regions": [ - "SCOTLAND" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "scotgov.bus.government_support", - "dimension_values": { - "funding_component": "all_government_support" - }, - "fiscal_start": "2024-04-01" - } - }, - { - "allocation": "uniform", - "label": "wales", - "regions": [ - "WALES" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "welshgov.local_transport.gross_expenditure", - "dimension_values": { - "expenditure_component": "Gross expenditure" - }, - "fiscal_start": "2024-04-01", - "sum_over": { - "service_line": [ - "Concessionary fares", - "Support to operators" - ] - } - } - }, - { - "allocation": "uniform", - "joint_columns": [ - "bus_subsidy_spending", - "rail_subsidy_spending" - ], - "label": "northern_ireland", - "regions": [ - "NORTHERN_IRELAND" - ], - "resource": "devolved_bus_finance.json", - "selector": { - "concept": "nithc.dfi_transaction_value", - "dimension_values": { - "mode_scope": "all_public_transport" - }, - "fiscal_start": "2024-04-01", - "sum_over": { - "funding_component": [ - "Public Service Obligation compensation", - "Concessionary fare compensation for a range of groups" - ] - } - } - } - ], - "columns": [ - "bus_subsidy_spending" - ], - "iterations": 1, - "kind": "rake_to_vendored_facts", - "scope": "all", - "weighted": true - }, - { - "basis": "value-side alternative recorded beside the raked column, never applied (microcosm#930, Mar\u00eda's ruling pending); England only, where DfT publishes the reimbursement and net support by area", + "basis": "bus support priced from the frame's journeys at the published support per boarding where the publisher gives the components and the boardings (DfT BUS05bi and BUS01 for London and England outside London, Scottish Transport Statistics for Scotland); 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, as Wales fares do (microcosm#930; Mar\u00eda's ruling of 2026-09-23 retiring the support rake)", "eligibility_column": "bus_pass_eligible", "fiscal_start": "2024-04-01", - "kind": "record_support_per_journey", + "kind": "price_bus_support", "population_period_value": 2024, "population_resource": "dft_bus_journeys.json", "pricing_areas": [ @@ -633,8 +525,45 @@ "series": "other_local_bus", "trips_basis": "published_series_rate", "trips_concept": "dft.other_local_bus_trips_per_person" + }, + { + "boardings": { + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, + "concessionary": { + "concept": "scotgov.bus.passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + }, + "groupby_value_id": "concessionary_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, + "label": "scotland", + "population_geography_ids": [ + "S92000003" + ], + "receipts": { + "concept": "scotgov.bus.operator_revenue", + "dimension_values": { + "revenue_component": "passenger_revenue" + }, + "groupby_value_id": "passenger_revenue", + "resource": "devolved_bus_finance.json" + }, + "regions": [ + "SCOTLAND" + ], + "series": "other_local_bus", + "trips_basis": "england_other_local_bus_rate_as_proxy", + "trips_concept": "dft.other_local_bus_trips_per_person" } ], + "raw_draw_regions": [ + "WALES", + "NORTHERN_IRELAND" + ], "support_areas": [ { "boardings": { @@ -700,6 +629,39 @@ "geography_id": "dft:england_outside_london", "resource": "dft_bus_journeys.json" } + }, + { + "boardings": { + "concept": "scotgov.bus.passenger_journeys", + "groupby_value_id": "all_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, + "concessionary": { + "concept": "scotgov.bus.passenger_journeys", + "dimension_values": { + "journey_category": "concessionary" + }, + "groupby_value_id": "concessionary_passenger_journeys", + "resource": "devolved_bus_finance.json" + }, + "label": "scotland", + "net_support": { + "concept": "scotgov.bus.government_support", + "dimension_values": { + "funding_component": "all_government_support" + }, + "resource": "devolved_bus_finance.json" + }, + "regions": [ + "SCOTLAND" + ], + "reimbursement": { + "concept": "scotgov.bus.government_support", + "dimension_values": { + "funding_component": "concessionary_fares" + }, + "resource": "devolved_bus_finance.json" + } } ], "support_column": "bus_subsidy_spending", @@ -710,7 +672,6 @@ "other_local_bus": "other_local_bus_trips" }, "unpriced_regions": [ - "SCOTLAND", "WALES", "NORTHERN_IRELAND" ] From eddcaa1d570049660ffcb856b283045c3d84bd9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 10:35:56 +0100 Subject: [PATCH 10/19] Clip bus support like the other ETB columns before pricing it: drop the support-clip exemption and pin its zero allowances (#930 C12) The support_clip gate for etb_services still exempted bus_subsidy_spending from the #890 rake days; the spine-t2 build blocked on it. The column is clipped to donor support like education and rail before the pricing step overrides it outside Wales and Northern Ireland, at the same clean-baseline allowance of zero clipped rows. Digests re-pinned. Co-Authored-By: Claude Fable 5.1 --- .../microcosm-build/src/microcosm/build/uk/gates.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 5443538eb..1242f6165 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -341,19 +341,19 @@ "dfe_education_spending", "rail_subsidy_spending" ], - "exempt_columns": [ - "bus_subsidy_spending" - ], + "exempt_columns": [], "max_clipped_low_rows_by_column": { + "bus_subsidy_spending": 0, "dfe_education_spending": 0, "rail_subsidy_spending": 0 }, "max_clipped_high_rows_by_column": { + "bus_subsidy_spending": 0, "dfe_education_spending": 0, "rail_subsidy_spending": 0 } }, - "notes": "Stage-time support-clip health gate over the ETB services receipt. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus support is exempt since microcosm#890: the declared rake to the published net support sets its level." + "notes": "Stage-time support-clip health gate over the ETB services receipt. Allowances pinned at the receipted spine-e baseline (2026-08-26): zero rows clipped on every non-exempt column, so any clipping is a real signal against a clean baseline; a missing allowance fails closed rather than skipping the comparison. Bus support is exempt since microcosm#890: the declared rake to the published net support sets its level. Since microcosm#930 (María's ruling of 2026-09-23 retiring the support rake) bus_subsidy_spending is clipped like the other two columns before the pricing step overrides it outside Wales and Northern Ireland, so it carries the same zero allowances and is no longer exempt." }, { "id": "uk_stage_etb_services_support_pricing", From b80b185516d8e8ae4022835d362e28e9b25d59b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 11:39:51 +0100 Subject: [PATCH 11/19] Rebase onto main b78f5a88: the nts_bus_travel stage records its household-mass receipt, surfaces regenerated, receipts Part H (#930) Main's #967 has every source stage declare and record a mass-conservation receipt the terminal family gate checks by reason; the NTS stage now does too. The coverage manifest, the H2 fixture and the gate digests are regenerated on the rebased tree; the ETB test that monkeypatched the retired support rake patches the pricing step instead. Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 46 +++++++++++++++++++ .../src/microcosm/build/uk/source_stages.json | 7 +++ .../src/microcosm/build/uk/spec/sources.yaml | 5 ++ .../build/uk_runtime/nts_bus_travel.py | 15 +++++- .../tests/test_uk_etb_services.py | 2 +- .../tests/test_uk_source_stages.py | 1 + .../src/microcosm/data/contract.py | 1 + .../parity/uk_spine/sources/fixture.json | 7 +++ 8 files changed, 82 insertions(+), 2 deletions(-) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 6122148bb..9bde143f1 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -341,3 +341,49 @@ alternatives are a different declared proxy region, or scaling the devolved seri published boardings ratio; (2) whether the ETB support rake now retires in favour of the support-per-journey value side (0.95 and 1.16 of the raked levels); (3) the vehicle-share gap (frame two-plus-car households 0.301 against NTS0205's 0.340) as a `was_wealth` follow-up. + +## Part H — the support rake retires: bus support priced from journeys (C12, 2026-09-23) + +María's ruling (2026-09-23): raking retires with the imputation; Wales and Northern Ireland keep +the raw ETB draw for support; the change goes into #954. Commits `f9b3fcc4` (the pricing step, +the retired `rake_to_vendored_facts` kind, `fact_raking.py` and the `fact_rake` check leaving with +their last consumer, the `uk_stage_etb_services_support_pricing` gate) and `742a2346` (the ETB +support-clip gate no longer exempts the column: spine-t2's first build blocked on that pin, the +column is clipped like education and rail at the same zero allowance), both rebased below. + +Declaration: `price_bus_support` on `etb_services` — support areas London and England outside +London (DfT BUS05bi reimbursement and net support, BUS01 boardings and concessionary boardings) +and Scotland (Scottish Transport Statistics: concessionary fares £392m inside all government +support £499m; 334m journeys, 183.6m concessionary); `raw_draw_regions: [WALES, +NORTHERN_IRELAND]` (no published Welsh boardings; the NITHC accounts carry bus and rail jointly). +Per household: reimbursement per concessionary boarding × its eligible persons' boardings plus +the rest of the net support per boarding × every boarding, boardings being the `nts_bus_travel` +trips times the fare pricing's boardings per resident trip. The published totals stay bound as +calibration targets. + +spine-t2 (code `742a2346`, same base as spine-t, 364 s): 24 of 24 stage gates. Support clip: +0 rows clipped on `bus_subsidy_spending` (donor max £14,074). Pricing receipt (design weights, +the FRS sample before the CGT clone; 13,373 households priced, 2,915 on the raw draw): + +- England outside London: £1.215 per concessionary boarding, £0.683 per boarding; frame boardings + 1,929m, eligible boarding share 0.208 beside the publisher's 0.281; support £1,856m (clipped + raw draw) → £1,807m priced against the published £1,895m, 0.953. +- London: £0.369 and £0.520; boardings 1,950m, eligible share 0.410 beside 0.273; £307m → £1,308m + against £1,130m, 1.158. +- Scotland: £2.135 and £0.320; boardings 519m (1.55× the published 334m, the proxy-region reading + of Part F), eligible share 0.581 beside 0.550; £224m → £810m against £499m, 1.623. +- Raw draw: Wales £133.6m (the published concessionary-plus-operator support is £131.5m), + Northern Ireland £84.0m (the joint bus-plus-rail cell was £111.7m). +- Weighted support in total: £2,605m before, £4,142m after (the priced areas' published total is + £3,524m). + +Twin diff spine-t → spine-t2 (`twin_diff_930_t2.sh`, expectation `spine-t2-payload-expectation.json`): +three observed differences, three expected, none unexpected. `bus_subsidy_spending` moves on every +row (priced in the three areas; Wales and Northern Ireland return from the raked value to the +clipped raw draw). `rail_subsidy_spending` and `rail_usage` move on exactly the 679 Northern +Ireland rows the retired joint bus-plus-rail cell used to scale. Weights, indices, every other +column and root attribute byte-equal. + +The `bus_support_pricing` gate recomputes the three areas' components and per-boarding rates from +the vendored rows at 1e-9 and reports the priced-over-published ratios (0.953, 1.158, 1.623) +without fencing them: the calibration targets act on them, as they act on the fares. 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 495d32403..82a2135f8 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1775,6 +1775,13 @@ { "kind": "support_clip", "range": "donor_realized" + }, + { + "kind": "record_mass_conservation_receipt", + "entity": "household", + "reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", + "declared_factor": 1.0, + "gate_coupling": "The terminal family gate requires a valid mass-conserving MassChangeRecord carrying exactly this stage-specific reason." } ], "outputs": [ 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 517b1ebd9..dfa034ac5 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1349,6 +1349,11 @@ stages: min_age: 65 - kind: support_clip range: donor_realized + - kind: record_mass_conservation_receipt + entity: household + reason: 'NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.' + declared_factor: 1.0 + gate_coupling: The terminal family gate requires a valid mass-conserving MassChangeRecord carrying exactly this stage-specific reason. outputs: - local_bus_use_band - bus_in_london_trips diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py index f8593975d..4d86eaf42 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py @@ -49,6 +49,7 @@ from microcosm.build.uk_runtime.frs_spine import read_pinned_tab from microcosm.build.uk_runtime.ledger_fact_vendoring import vendored_rows from microcosm.build.uk_runtime.national_frame import ( + uk_household_mass_conservation_receipt, uk_household_weight_kind, uk_national_frame, uk_time_period, @@ -62,6 +63,13 @@ from microcosm.frame.rules import assert_rules_engine_country UK_NTS_BUS_TRAVEL_STAGE_NAME = "nts_bus_travel" +#: The household-mass receipt this stage records (the manifest's +#: ``record_mass_conservation_receipt`` operation repeats it): the terminal +#: family gate requires exactly this reason on a valid mass-conserving record. +UK_NTS_BUS_TRAVEL_MASS_CONSERVATION_REASON = ( + "NTS bus-travel imputation on the source spine: household weights pass " + "through unchanged and total household mass is conserved." +) UK_NTS_HOUSEHOLD_TAB_ROLE = "nts_household_tab" UK_NTS_INDIVIDUAL_TAB_ROLE = "nts_individual_tab" UK_NTS_TRIP_TAB_ROLE = "nts_trip_tab" @@ -1424,7 +1432,12 @@ def __call__(self, frame: Frame) -> Frame: time_period=uk_time_period(frame), weight_kind=uk_household_weight_kind(frame), household_weights=household_weights, - mass_log=frame.mass_log, + mass_log=( + *frame.mass_log, + uk_household_mass_conservation_receipt( + frame, UK_NTS_BUS_TRAVEL_MASS_CONSERVATION_REASON + ), + ), ) validate_uk_national_frame(result) self.last_fit_weight_records = imputation.fit_weight_records diff --git a/packages/microcosm-build/tests/test_uk_etb_services.py b/packages/microcosm-build/tests/test_uk_etb_services.py index 75fbf005b..ec58c4d88 100644 --- a/packages/microcosm-build/tests/test_uk_etb_services.py +++ b/packages/microcosm-build/tests/test_uk_etb_services.py @@ -394,7 +394,7 @@ def test_stage_transform_records_its_mass_conservation_receipt( clipped=d, receipt=SimpleNamespace(evidence=lambda: {}) ), ) - monkeypatch.setattr(module, "etb_bus_support_rake", lambda _s, d, **_: (d, {})) + monkeypatch.setattr(module, "etb_bus_support_pricing", lambda _s, d, **_: (d, {})) monkeypatch.setattr( module, "allocate_nhs_by_age_gender", lambda *_, **__: (nhs, {}) ) diff --git a/packages/microcosm-build/tests/test_uk_source_stages.py b/packages/microcosm-build/tests/test_uk_source_stages.py index 0b954964d..6cc5b033c 100644 --- a/packages/microcosm-build/tests/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/test_uk_source_stages.py @@ -647,6 +647,7 @@ def test_e3_operation_kinds_are_declared_in_order(self) -> None: "assign_trips_from_band_means", "assign_bus_pass_eligibility", "support_clip", + "record_mass_conservation_receipt", ] assert [op.kind for op in stages["lcfs_consumption"].operations] == [ "derive", diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 79e26e7f6..7a0eaecc7 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -809,6 +809,7 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "77eace424e352172496f8fd99dbf68f858514198f87f6c6a6b33353d7eff55ad" "a7250c519e79e22d366316cd4943f5f4bd2cc86a0e76b919ee2ff2eacb2335f3" "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" + "0bb5ca207d76ce6d2be68ba4c0a7dfb982e767165634c15bdb539c921e9edc1f" ), "policy_sha256": ( "11fe34504eecefa7ca584ccecd3c8c6131db71aa2f96f0d6337b2c9fbd55a738" 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 89f82d4d0..05c9a7580 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 @@ -3964,6 +3964,13 @@ { "kind": "support_clip", "range": "donor_realized" + }, + { + "declared_factor": 1, + "entity": "household", + "gate_coupling": "The terminal family gate requires a valid mass-conserving MassChangeRecord carrying exactly this stage-specific reason.", + "kind": "record_mass_conservation_receipt", + "reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved." } ], "outputs": [ From 9d8e8546e6d3c0efc9789b0a50a10cb8543170e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 11:57:22 +0100 Subject: [PATCH 12/19] Read the NTS stage and ticket tables: the single-fare share of each person's fare-paying boardings (#930 C13) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit María's ask of 2026-09-23, after the fare-cap question: the boardings a per-journey cap binds on. Two more pinned SN 5340 artifacts (the Stage table, a boarding per row with the cost paid at the point of use and the held ticket used; the Ticket table, the season tickets and passes held, concessionary codes 7 to 11). Every diary bus boarding is classed as paid at the point of use, a season ticket or pass, a concessionary pass, free with no ticket, or unknown; per series, residence group and band the share of point-of-use boardings among fare-paying ones is assigned to each person as local_bus_single_fare_share (trips-weighted across the two series). The fare paid per boarding by residence group and survey year, the boarding-class shares and the NTS boardings per bus trip are receipted; nothing derived from the licensed rows is committed. The column joins the export surface and the stage's E6 support bounds (0 to 1); the spine tool takes --nts-stage-tab and --nts-ticket-tab; the graph sources, the H2 fixture (synthetic stages and tickets), the coverage manifest and the gate digests follow. policyengine-uk#1871 carries the parameter side. Co-Authored-By: Claude Fable 5.1 --- .../930-nts-single-fare-share.added.md | 1 + experiments/930-nts-bus-journeys-receipts.md | 39 ++ .../spec_engine/schema/sources.schema.json | 48 +- .../src/microcosm/build/uk/gates.json | 1 + .../uk/nts_bus_travel_support_bounds.json | 6 + .../src/microcosm/build/uk/source_stages.json | 47 +- .../src/microcosm/build/uk/spec/sources.yaml | 40 +- .../src/microcosm/build/uk_runtime/graph.py | 11 +- .../build/uk_runtime/graph_kernels.py | 8 + .../build/uk_runtime/nts_bus_travel.py | 389 +++++++++++- .../build/uk_runtime/terminal_gates.py | 1 + .../tests/test_uk_consumption_resources.py | 8 + .../tests/test_uk_frs_spine.py | 2 + .../microcosm-build/tests/test_uk_graph.py | 2 + .../tests/test_uk_nts_bus_travel.py | 125 +++- .../src/microcosm/data/contract.py | 3 +- .../parity/uk_spine/sources/fixture.json | 47 +- .../parity/uk_spine/sources/nts_stage.csv | 557 ++++++++++++++++++ .../parity/uk_spine/sources/nts_ticket.csv | 97 +++ tools/build_uk_e6_support_bounds.py | 22 +- tools/build_uk_frs_spine.py | 20 + tools/graph_uk_spine_fixture.py | 62 +- 22 files changed, 1510 insertions(+), 26 deletions(-) create mode 100644 changelog.d/930-nts-single-fare-share.added.md create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_stage.csv create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_ticket.csv diff --git a/changelog.d/930-nts-single-fare-share.added.md b/changelog.d/930-nts-single-fare-share.added.md new file mode 100644 index 000000000..bdc3415aa --- /dev/null +++ b/changelog.d/930-nts-single-fare-share.added.md @@ -0,0 +1 @@ +The `nts_bus_travel` stage reads the National Travel Survey stage and ticket tables (two more pinned SN 5340 artifacts) and gives every person `local_bus_single_fare_share`, the share of their fare-paying local-bus boardings paid at the point of use rather than covered by a season ticket or non-concessionary pass: the boardings a per-journey fare cap binds on (microcosm#930, María's ask of 2026-09-23; the parameter side is policyengine-uk#1871). A diary bus stage is a boarding (`NumBoardings` counts the vehicles) classed by how it was paid for: no ticket record and a positive boarding cost is a fare paid at the point of use, a ticket record with a concessionary code (`SpecialTicket_B01ID` 7 to 11) a concessionary pass, any other ticket record a season ticket or pass, no record and zero cost free travel. Per band and residence group the share is the boarding-weighted ratio of point-of-use to all fare-paying boardings, assigned per person as the trips-weighted combination of the two series' cell shares; the fare paid per boarding by residence group and survey year, the boarding-class shares and the NTS boardings per bus trip are receipted beside it, nothing derived from the licensed rows committed. The column joins the export surface and the stage's E6 support bounds (0 to 1); the spine tool takes `--nts-stage-tab` and `--nts-ticket-tab`, and the H2 fixture's synthetic tabs gain stages and tickets. diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 9bde143f1..7d0d14002 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -387,3 +387,42 @@ column and root attribute byte-equal. The `bus_support_pricing` gate recomputes the three areas' components and per-boarding rates from the vendored rows at 1e-9 and reports the priced-over-published ratios (0.953, 1.158, 1.623) without fencing them: the calibration targets act on them, as they act on the fares. + +## Part I — the stage and ticket tables: the single-fare share (C13, 2026-09-23) + +María's ask (2026-09-23, after the fare-cap question): read the ticket table for the single-fare +share. The NTS extract's Stage table records every boarding (`NumBoardings` counts the vehicles on a +stage), the cost paid at the point of use (`StageFareCost`) and the held ticket used (`IndTicketID`); +the Ticket table records the season tickets and passes a person holds (`SpecialTicket_B01ID`: 1–6 +non-concessionary, 7–11 concessionary, from the deposited lookup tables). Pinned as two further +artifacts: `stage_eul_2002-2024.tab` 1,039,281,193 bytes sha256 `4a6015ed…`, `ticket_eul_2002-2024.tab` +8,655,532 bytes sha256 `276a99bd…`. + +Boarding payment classes on the 2022–24 diary (England, bus stages, unweighted counts read while +designing the declaration): 30,403 bus boardings; 12,634 paid at the point of use (no ticket record, +positive cost), 10,399 on concessionary passes, 3,450 on non-concessionary season tickets or passes, +2,758 free with no ticket (children, by age), 1,162 with no cost recorded. Single-fare share of +fare-paying boardings 0.79 (London series 0.90, other local bus 0.71). Design-weighted by residence +group and survey year (W2): outside London the point-of-use share of boardings rose from 0.34 (2022) +to 0.43 (2023) and 0.46 (2024) while the season-ticket share fell from 0.25 to 0.16 and 0.15, the +diary's reading of the £2 cap's pass-to-single shift; the fare paid per boarding outside London +averaged £2.10 in 2022 and £1.95 and £2.02 under the cap, median £2.00 in all three years; London +£1.57, £1.85, £1.87 (median £1.65 then £1.75, the TfL single). The NTS boardings per bus trip are 1.13 +(London series 1.15, other local bus 1.13): the declared translation for England outside London +(1.12) is the same number from the publisher's side, and the London series' 2.37 is twice it, the +scope difference (non-resident boardings in TfL's count) Part D declared. + +Declaration and runtime: the stage classes every bus stage, annualises each person's weighted +boardings by class and series (the trip's weight on the household-and-trip basis, times the +vehicles boarded), takes per series, residence group and band the boarding-weighted share of +point-of-use boardings among fare-paying ones (a cell without fare-paying boardings takes its +group's share, then England's, receipted), and assigns each person the trips-weighted combination +of the two series' cell shares as `local_bus_single_fare_share` (a person with no trips takes the +plain mean). The column joins the export surface (person grain), the stage's support clip and E6 +bounds (0 to 1); the receipts carry the class shares, fares and boardings per trip above. No +published table fences the share (DfT does not publish boardings by ticket type), so it is a +receipt line, not a gate. The parameter side, a per-journey cap on the single-fare boardings of +fare-paying persons, is policyengine-uk#1871. + +spine-t3 (the rebased tree plus C13) and its diff against spine-t2, the calibration and the anatomy +follow below. 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 178837ff9..5e5d962a0 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 @@ -8785,7 +8785,16 @@ "sex", "main_mode", "trip_weight", - "short_walk_multiplier" + "short_walk_multiplier", + "stage_id", + "stage_trip_id", + "stage_individual_id", + "stage_ticket_id", + "stage_mode", + "stage_boardings", + "stage_fare_cost", + "ticket_id", + "ticket_special" ], "properties": { "household_id": { @@ -8832,6 +8841,33 @@ }, "short_walk_multiplier": { "type": "string" + }, + "stage_id": { + "type": "string" + }, + "stage_trip_id": { + "type": "string" + }, + "stage_individual_id": { + "type": "string" + }, + "stage_ticket_id": { + "type": "string" + }, + "stage_mode": { + "type": "string" + }, + "stage_boardings": { + "type": "string" + }, + "stage_fare_cost": { + "type": "string" + }, + "ticket_id": { + "type": "string" + }, + "ticket_special": { + "type": "string" } } }, @@ -8844,7 +8880,8 @@ "female", "main_mode", "frequency", - "age_band" + "age_band", + "concessionary_ticket" ], "properties": { "region": { @@ -8879,6 +8916,13 @@ "additionalProperties": { "type": "integer" } + }, + "concessionary_ticket": { + "type": "array", + "minItems": 1, + "items": { + "type": "integer" + } } } }, diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 1242f6165..d394bb88d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -751,6 +751,7 @@ "person.is_parent", "person.is_uc_claimant", "person.legacy_jobseeker_proxy", + "person.local_bus_single_fare_share", "person.local_bus_trips", "person.local_bus_use_band", "person.ons_family_index", diff --git a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json index 31b7a1433..f1719df59 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json +++ b/packages/microcosm-build/src/microcosm/build/uk/nts_bus_travel_support_bounds.json @@ -8,6 +8,8 @@ "household_tab_sha256": "b70252b606b13c2b7f32e6da09e202e47514f6414045a017e77deb1d2a87ceb7", "individual_tab_sha256": "e8b568497f99aeced2b379d853a1254759cdcb4409acc0b9ff3ea3d95c1f5e8d", "trip_tab_sha256": "878b61c9fdafcbc1a85913f3af4889913bcf73c294f0221e84b3651a404284c4", + "stage_tab_sha256": "4a6015ed54abc32b48e45a5af663d44a39e1147c7ff8c2e087aa29828665b64c", + "ticket_tab_sha256": "276a99bd30ff4aa3506d2126f6fd269db2f2d0265b5231a55aaefca9212363a0", "sdc_treatment": "Exact donor min/max values are rounded outward to one significant figure before commit." }, "bounds": { @@ -15,6 +17,10 @@ 0.0, 2000 ], + "local_bus_single_fare_share": [ + 0.0, + 1 + ], "local_bus_trips": [ 0.0, 2000 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 82a2135f8..49cd97486 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1480,6 +1480,30 @@ "locator": "caller-supplied local input", "runtime_sha256_required": true }, + { + "role": "nts_stage_tab", + "kind": "private_microdata", + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "stage_eul_2002-2024.tab", + "sha256": "4a6015ed54abc32b48e45a5af663d44a39e1147c7ff8c2e087aa29828665b64c", + "size_bytes": 1039281193, + "access": "private_local_input", + "locator": "caller-supplied local input", + "runtime_sha256_required": true + }, + { + "role": "nts_ticket_tab", + "kind": "private_microdata", + "ukds_study_number": 5340, + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "ticket_eul_2002-2024.tab", + "sha256": "276a99bd30ff4aa3506d2126f6fd269db2f2d0265b5231a55aaefca9212363a0", + "size_bytes": 8655532, + "access": "private_local_input", + "locator": "caller-supplied local input", + "runtime_sha256_required": true + }, { "role": "nts_trip_rates", "resource": "nts_trip_rates.json", @@ -1540,7 +1564,16 @@ "frequency": "OrdBus2Freq_B01ID", "main_mode": "MainMode_B04ID", "trip_weight": "W5", - "short_walk_multiplier": "JJXSC" + "short_walk_multiplier": "JJXSC", + "stage_id": "StageID", + "stage_trip_id": "TripID", + "stage_individual_id": "IndividualID", + "stage_ticket_id": "IndTicketID", + "stage_mode": "StageMode_B04ID", + "stage_boardings": "NumBoardings", + "stage_fare_cost": "StageFareCost", + "ticket_id": "IndTicketID", + "ticket_special": "SpecialTicket_B01ID" }, "codes": { "region": { @@ -1564,6 +1597,13 @@ "bus_in_london": 7, "other_local_bus": 8 }, + "concessionary_ticket": [ + 7, + 8, + 9, + 10, + 11 + ], "frequency": { "1": 6, "2": 6, @@ -1601,7 +1641,7 @@ "21": 85 } }, - "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures)." + "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures). Stage and ticket tables, verified 2026-09-23. A stage is a boarding (NumBoardings counts the vehicles), StageMode_B04ID carries the trip-mode categories, StageFareCost is the boarding cost paid at the point of use and IndTicketID links a stage to a held ticket; SpecialTicket_B01ID codes 7 to 11 are the concessionary passes (older people, scholars, disabled persons, subsidised tokens, other concessionary), 1 to 6 non-concessionary season tickets and passes. A boarding with no ticket record and a positive cost paid a single, return or day fare at the point of use; with no record and zero cost it travelled free (children, in the main); with no cost recorded its class is unknown." }, { "kind": "materialize_rules_engine_predictors", @@ -1790,6 +1830,7 @@ "other_local_bus_trips", "local_bus_trips", "bus_pass_eligible", + "local_bus_single_fare_share", "household_local_bus_trips" ], "nonnegative_outputs": [ @@ -1799,7 +1840,7 @@ "local_bus_trips", "household_local_bus_trips" ], - "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed." + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage and ticket tables class every diary bus boarding by how it was paid for (at the point of use, a season ticket or pass, a concessionary pass, free) and give each person the share of fare-paying boardings paid at the point of use for their band and residence group (local_bus_single_fare_share), the boardings a per-journey fare cap binds on, with the fare paid per boarding by residence group and survey year receipted beside it (microcosm#930 C13, María's ask of 2026-09-23). The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed." }, { "stage": "lcfs_consumption", 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 dfa034ac5..f9315ede2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1123,6 +1123,26 @@ stages: access: private_local_input locator: caller-supplied local input runtime_sha256_required: true + - role: nts_stage_tab + kind: private_microdata + ukds_study_number: 5340 + doi: 10.5255/UKDA-SN-5340-19 + filename: stage_eul_2002-2024.tab + sha256: 4a6015ed54abc32b48e45a5af663d44a39e1147c7ff8c2e087aa29828665b64c + size_bytes: 1039281193 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true + - role: nts_ticket_tab + kind: private_microdata + ukds_study_number: 5340 + doi: 10.5255/UKDA-SN-5340-19 + filename: ticket_eul_2002-2024.tab + sha256: 276a99bd30ff4aa3506d2126f6fd269db2f2d0265b5231a55aaefca9212363a0 + size_bytes: 8655532 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true - role: nts_trip_rates resource: nts_trip_rates.json kind: public_aggregate_reference @@ -1173,6 +1193,15 @@ stages: main_mode: MainMode_B04ID trip_weight: W5 short_walk_multiplier: JJXSC + stage_id: StageID + stage_trip_id: TripID + stage_individual_id: IndividualID + stage_ticket_id: IndTicketID + stage_mode: StageMode_B04ID + stage_boardings: NumBoardings + stage_fare_cost: StageFareCost + ticket_id: IndTicketID + ticket_special: SpecialTicket_B01ID codes: region: '1': NORTH_EAST @@ -1192,6 +1221,12 @@ stages: main_mode: bus_in_london: 7 other_local_bus: 8 + concessionary_ticket: + - 7 + - 8 + - 9 + - 10 + - 11 frequency: '1': 6 '2': 6 @@ -1226,7 +1261,7 @@ stages: '19': 75 '20': 80 '21': 85 - codebook_status: verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures). + codebook_status: verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures). Stage and ticket tables, verified 2026-09-23. A stage is a boarding (NumBoardings counts the vehicles), StageMode_B04ID carries the trip-mode categories, StageFareCost is the boarding cost paid at the point of use and IndTicketID links a stage to a held ticket; SpecialTicket_B01ID codes 7 to 11 are the concessionary passes (older people, scholars, disabled persons, subsidised tokens, other concessionary), 1 to 6 non-concessionary season tickets and passes. A boarding with no ticket record and a positive cost paid a single, return or day fare at the point of use; with no record and zero cost it travelled free (children, in the main); with no cost recorded its class is unknown. - kind: materialize_rules_engine_predictors predictors: - household_gross_income @@ -1360,6 +1395,7 @@ stages: - other_local_bus_trips - local_bus_trips - bus_pass_eligible + - local_bus_single_fare_share - household_local_bus_trips nonnegative_outputs: - local_bus_use_band @@ -1367,7 +1403,7 @@ stages: - other_local_bus_trips - local_bus_trips - household_local_bus_trips - notes: Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed. + notes: Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage and ticket tables class every diary bus boarding by how it was paid for (at the point of use, a season ticket or pass, a concessionary pass, free) and give each person the share of fare-paying boardings paid at the point of use for their band and residence group (local_bus_single_fare_share), the boardings a per-journey fare cap binds on, with the fare paid per boarding by residence group and survey year receipted beside it (microcosm#930 C13, María's ask of 2026-09-23). The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed. - stage: lcfs_consumption survey: Living Costs and Food Survey 2023-24 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. 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 410db23f4..dbd4c73f3 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -114,7 +114,13 @@ "frs_education": ("frs",), "frs_legacy_proxies": ("frs",), "was_wealth": ("was",), - "nts_bus_travel": ("nts_household", "nts_individual", "nts_trip"), + "nts_bus_travel": ( + "nts_household", + "nts_individual", + "nts_trip", + "nts_stage", + "nts_ticket", + ), "lcfs_consumption": ("lcfs_household", "lcfs_person"), "etb_vat": ("etb",), "etb_services": ("etb",), @@ -128,6 +134,8 @@ "nts_household": "Pinned local NTS household donor table.", "nts_individual": "Pinned local NTS individual donor table.", "nts_trip": "Pinned local NTS trip donor table.", + "nts_stage": "Pinned local NTS stage donor table.", + "nts_ticket": "Pinned local NTS ticket donor table.", "lcfs_household": "Pinned local LCFS household donor table.", "lcfs_person": "Pinned local LCFS person donor table.", "etb": "Pinned local ETB household donor table.", @@ -539,6 +547,7 @@ def _cells( ("bus_in_london_trips", "other_local_bus_trips", "local_bus_trips"), ), _Cell("person", "bus_pass_eligible", "bool"), + _Cell("person", "local_bus_single_fare_share", "float64"), _Cell("household", "household_local_bus_trips", "float64"), ), "regional_property_uprating": _cells( 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 06d6f8437..c47d74f68 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 @@ -414,6 +414,12 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: nts_trip = pd.read_csv( _fixture_input(source, inputs, "nts_trip"), float_precision="round_trip" ) + nts_stage = pd.read_csv( + _fixture_input(source, inputs, "nts_stage"), float_precision="round_trip" + ) + nts_ticket = pd.read_csv( + _fixture_input(source, inputs, "nts_ticket"), float_precision="round_trip" + ) spi_path = _fixture_input(source, inputs, "spi_donor") spi_donor = pd.read_csv(spi_path, float_precision="round_trip") hmrc_targets_path = _fixture_input(source, inputs, "hmrc_income_targets") @@ -480,6 +486,8 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: nts_household=nts_household, nts_individual=nts_individual, nts_trip=nts_trip, + nts_stage=nts_stage, + nts_ticket=nts_ticket, ), "regional_property_uprating": UKRegionalPropertyUpratingStageTransform( stage=stages["regional_property_uprating"] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py index 4d86eaf42..326c6eb65 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py @@ -73,6 +73,8 @@ UK_NTS_HOUSEHOLD_TAB_ROLE = "nts_household_tab" UK_NTS_INDIVIDUAL_TAB_ROLE = "nts_individual_tab" UK_NTS_TRIP_TAB_ROLE = "nts_trip_tab" +UK_NTS_STAGE_TAB_ROLE = "nts_stage_tab" +UK_NTS_TICKET_TAB_ROLE = "nts_ticket_tab" CLEAN_NTS_TRAVEL_TABLES_KIND = "clean_nts_travel_tables" IMPUTE_BUS_USE_BAND_KIND = "impute_bus_use_band" @@ -95,13 +97,40 @@ TRIPS_COLUMN = "local_bus_trips" ELIGIBLE_COLUMN = "bus_pass_eligible" HOUSEHOLD_TRIPS_COLUMN = "household_local_bus_trips" +#: Share of a person's fare-paying boardings paid at the point of use (a +#: single, return or day fare bought for the journey) rather than covered by a +#: season ticket or non-concessionary pass: the boardings a per-journey fare +#: cap binds on (microcosm#930 C13, from the NTS stage and ticket tables). +SINGLE_FARE_SHARE_COLUMN = "local_bus_single_fare_share" UK_NTS_PERSON_OUTPUT_COLUMNS: tuple[str, ...] = ( BAND_COLUMN, SERIES_TRIP_COLUMNS[BUS_IN_LONDON], SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], TRIPS_COLUMN, ELIGIBLE_COLUMN, + SINGLE_FARE_SHARE_COLUMN, ) +#: Boarding payment classes read from the stage and ticket tables. +BOARDING_FARE_PAID = "fare_paid" +BOARDING_PASS = "season_or_pass" +BOARDING_CONCESSIONARY = "concessionary_pass" +BOARDING_FREE = "free_no_ticket" +BOARDING_UNKNOWN = "unknown" +BOARDING_CLASSES: tuple[str, ...] = ( + BOARDING_FARE_PAID, + BOARDING_PASS, + BOARDING_CONCESSIONARY, + BOARDING_FREE, + BOARDING_UNKNOWN, +) + + +def boarding_class_column(series: str, boarding_class: str) -> str: + """The donor column holding a person's annual weighted boardings of a class.""" + + return f"{boarding_class}_boardings_{series}" + + UK_NTS_HOUSEHOLD_OUTPUT_COLUMNS: tuple[str, ...] = (HOUSEHOLD_TRIPS_COLUMN,) UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS: tuple[str, ...] = ( *UK_NTS_PERSON_OUTPUT_COLUMNS, @@ -113,6 +142,7 @@ SERIES_TRIP_COLUMNS[BUS_IN_LONDON], SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], TRIPS_COLUMN, + SINGLE_FARE_SHARE_COLUMN, ) #: Vendored resources the stage reads (the register's consumer truthfulness). UK_NTS_TRIP_RATES_RESOURCE = "nts_trip_rates.json" @@ -209,6 +239,16 @@ class NTSColumns: main_mode: str trip_weight: str short_walk_multiplier: str + stage_id: str + stage_trip_id: str + stage_individual_id: str + stage_ticket_id: str + stage_mode: str + stage_boardings: str + stage_fare_cost: str + ticket_id: str + ticket_special: str + concessionary_ticket_codes: frozenset[int] region_codes: Mapping[int, str] london_region_code: int income_band_codes: Mapping[int, int] @@ -239,6 +279,15 @@ def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: "main_mode", "trip_weight", "short_walk_multiplier", + "stage_id", + "stage_trip_id", + "stage_individual_id", + "stage_ticket_id", + "stage_mode", + "stage_boardings", + "stage_fare_cost", + "ticket_id", + "ticket_special", ) missing = [name for name in required if not isinstance(columns.get(name), str)] if missing: @@ -297,6 +346,14 @@ def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: raise NTSBusTravelError( f"codes.main_mode must name exactly the series {list(SERIES)}." ) + concessionary_ticket_codes = frozenset( + int(code) for code in codes.get("concessionary_ticket", ()) + ) + if not concessionary_ticket_codes: + raise NTSBusTravelError( + "codes.concessionary_ticket must list the ticket-table codes of the " + "concessionary passes." + ) frequency_codes = { int(code): int(band) for code, band in _mapping( @@ -328,6 +385,16 @@ def from_parameters(cls, parameters: Mapping[str, Any]) -> NTSColumns: main_mode=columns["main_mode"].lower(), trip_weight=columns["trip_weight"].lower(), short_walk_multiplier=columns["short_walk_multiplier"].lower(), + stage_id=columns["stage_id"].lower(), + stage_trip_id=columns["stage_trip_id"].lower(), + stage_individual_id=columns["stage_individual_id"].lower(), + stage_ticket_id=columns["stage_ticket_id"].lower(), + stage_mode=columns["stage_mode"].lower(), + stage_boardings=columns["stage_boardings"].lower(), + stage_fare_cost=columns["stage_fare_cost"].lower(), + ticket_id=columns["ticket_id"].lower(), + ticket_special=columns["ticket_special"].lower(), + concessionary_ticket_codes=concessionary_ticket_codes, region_codes=region_codes, london_region_code=int(london[0]), income_band_codes=income_codes, @@ -390,6 +457,8 @@ def clean_nts_travel_tables( household: pd.DataFrame, individual: pd.DataFrame, trip: pd.DataFrame, + stage: pd.DataFrame | None = None, + ticket: pd.DataFrame | None = None, *, columns: NTSColumns, cars_clip: tuple[int, int] = (0, 5), @@ -402,7 +471,13 @@ def clean_nts_travel_tables( ``income_band`` (1..3), ``weight`` (W2, the diary household weight), the interview ``local_bus_use_band`` when the extract carries it, and the annual diary trips per series (52.14 x sum of trip weight x short-walk - multiplier over the person's trips whose main mode is that series). + multiplier over the person's trips whose main mode is that series). With the + stage and ticket tables, also the person's annual weighted bus boardings by + payment class per series: paid at the point of use (no ticket record and a + positive boarding cost), a non-concessionary season ticket or pass, a + concessionary pass (the declared ticket codes), free with no ticket, or + unknown (no cost recorded); the share of fare-paying boardings paid at the + point of use is the single-fare share a per-journey cap binds on. """ hh = _lower(household) @@ -545,6 +620,99 @@ def clean_nts_travel_tables( person[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + person[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]] ) + ticket_receipt: dict[str, Any] | None = None + if stage is not None and ticket is not None: + # Each bus stage is a boarding (NumBoardings counts the vehicles); it + # inherits its trip's weight and is classed by how it was paid for. + stg = _lower(stage) + tkt = _lower(ticket) + _require( + stg, + ( + columns.stage_id, + columns.stage_trip_id, + columns.stage_individual_id, + columns.stage_ticket_id, + columns.stage_mode, + columns.stage_boardings, + columns.stage_fare_cost, + ), + "stage", + ) + _require(tkt, (columns.ticket_id, columns.ticket_special), "ticket") + stg = stg.loc[ + stg[columns.stage_individual_id].isin(person[columns.individual_id]) + ].copy() + stage_mode = pd.to_numeric(stg[columns.stage_mode], errors="coerce") + series_codes = {code: series for series, code in columns.mode_codes.items()} + stg = stg.loc[stage_mode.isin(list(series_codes))].copy() + stg["series"] = pd.to_numeric(stg[columns.stage_mode], errors="coerce").map( + series_codes + ) + trip_factor = pd.to_numeric(tr[columns.trip_weight], errors="coerce").fillna( + 0.0 + ) * pd.to_numeric(tr[columns.short_walk_multiplier], errors="coerce").fillna( + 0.0 + ) + if columns.trip_weight_basis == TRIP_WEIGHT_HOUSEHOLD_AND_TRIP: + trip_factor = trip_factor / tr[columns.individual_id].map( + person.set_index(columns.individual_id)["weight"] + ).to_numpy(dtype=float) + trip_factor.index = tr[columns.trip_id].to_numpy() + stg["trip_factor"] = ( + stg[columns.stage_trip_id] + .map(trip_factor) + .fillna(0.0) + .to_numpy(dtype=float) + ) + stg["boardings"] = pd.to_numeric( + stg[columns.stage_boardings], errors="coerce" + ).fillna(1.0) + ticket_special = pd.to_numeric( + tkt.set_index(columns.ticket_id)[columns.ticket_special], errors="coerce" + ) + special = stg[columns.stage_ticket_id].map(ticket_special) + has_ticket = pd.to_numeric( + stg[columns.stage_ticket_id], errors="coerce" + ).notna() + fare = pd.to_numeric(stg[columns.stage_fare_cost], errors="coerce") + concessionary = has_ticket & special.isin( + list(columns.concessionary_ticket_codes) + ) + stg["boarding_class"] = np.select( + [ + concessionary.to_numpy(), + (has_ticket & ~concessionary).to_numpy(), + (~has_ticket & (fare > 0)).to_numpy(), + (~has_ticket & (fare == 0)).to_numpy(), + ], + [BOARDING_CONCESSIONARY, BOARDING_PASS, BOARDING_FARE_PAID, BOARDING_FREE], + BOARDING_UNKNOWN, + ) + stg["weighted_boardings"] = stg["trip_factor"] * stg["boardings"] + stg["fare_per_boarding"] = np.where( + (stg["boarding_class"] == BOARDING_FARE_PAID) & (stg["boardings"] > 0), + fare.to_numpy(dtype=float) / stg["boardings"].to_numpy(dtype=float), + np.nan, + ) + for series in SERIES: + for boarding_class in BOARDING_CLASSES: + cell = (stg["series"] == series) & ( + stg["boarding_class"] == boarding_class + ) + per_person = ( + stg.loc[cell, "weighted_boardings"] + .groupby(stg.loc[cell, columns.stage_individual_id]) + .sum() + ) + person[boarding_class_column(series, boarding_class)] = ( + person[columns.individual_id] + .map(per_person) + .fillna(0.0) + .to_numpy(dtype=float) + * WEEKS_IN_YEAR + ) + ticket_receipt = _ticket_receipt(stg, person, hh_keep, columns) person = person.rename( columns={ columns.individual_id: "individual_id", @@ -568,6 +736,12 @@ def clean_nts_travel_tables( SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], TRIPS_COLUMN, ] + if ticket_receipt is not None: + keep.extend( + boarding_class_column(series, boarding_class) + for series in SERIES + for boarding_class in BOARDING_CLASSES + ) if frequency_source == FREQUENCY_SOURCE_INTERVIEW: keep.append(BAND_COLUMN) person = person[keep].reset_index(drop=True) @@ -592,10 +766,97 @@ def clean_nts_travel_tables( series: float(np.average(person[column], weights=person["weight"])) for series, column in SERIES_TRIP_COLUMNS.items() }, + "ticket_tables_read": ticket_receipt is not None, + "boarding_classes": ticket_receipt, } return NTSDonor(person=person, frequency_source=frequency_source, receipt=receipt) +def _ticket_receipt( + stg: pd.DataFrame, + person: pd.DataFrame, + hh_keep: pd.DataFrame, + columns: NTSColumns, +) -> dict[str, Any]: + """Boarding payment classes, fares paid and boardings per trip on the diary. + + Weighted by the trip factor (the trip weight on the diary household + weight basis); by residence group and survey year, so the fare paid at the + point of use can be read before and after a fare cap. Disclosure-safe + aggregates only. + """ + + person_group = person.set_index(columns.individual_id)["residence_group"] + person_year = person.set_index(columns.individual_id)["survey_year"] + group = stg[columns.stage_individual_id].map(person_group).astype(str) + year = pd.to_numeric( + stg[columns.stage_individual_id].map(person_year), errors="coerce" + ) + w = stg["weighted_boardings"].to_numpy(dtype=float) + out: dict[str, Any] = {"by_group_and_year": {}, "by_series": {}} + for g in RESIDENCE_GROUPS: + for y in sorted(int(v) for v in year.dropna().unique()): + cell = (group == g) & (year == y) + if w[cell].sum() <= 0: + continue + classes = { + boarding_class: float( + w[cell & (stg["boarding_class"] == boarding_class)].sum() + / w[cell].sum() + ) + for boarding_class in BOARDING_CLASSES + } + paid = cell & (stg["boarding_class"] == BOARDING_FARE_PAID) + fares = stg.loc[paid, "fare_per_boarding"].to_numpy(dtype=float) + fw = w[paid] + ok = np.isfinite(fares) & (fw > 0) + out["by_group_and_year"][f"{g}:{y}"] = { + "boarding_class_shares": classes, + "fare_paying_single_share": ( + classes[BOARDING_FARE_PAID] + / (classes[BOARDING_FARE_PAID] + classes[BOARDING_PASS]) + if classes[BOARDING_FARE_PAID] + classes[BOARDING_PASS] > 0 + else None + ), + "mean_fare_paid_per_boarding": ( + float(np.average(fares[ok], weights=fw[ok])) if ok.any() else None + ), + "median_fare_paid_per_boarding": ( + float(np.median(fares[ok])) if ok.any() else None + ), + "boardings_unweighted": int(cell.sum()), + } + for series in SERIES: + cell = stg["series"] == series + paid = cell & (stg["boarding_class"] == BOARDING_FARE_PAID) + passes = cell & (stg["boarding_class"] == BOARDING_PASS) + out["by_series"][series] = { + "single_share_of_fare_paying_boardings": ( + float(w[paid].sum() / (w[paid].sum() + w[passes].sum())) + if w[paid].sum() + w[passes].sum() > 0 + else None + ), + "boardings_per_bus_trip": ( + float( + stg.loc[cell, "weighted_boardings"].sum() + / stg.loc[cell] + .groupby(columns.stage_trip_id)["trip_factor"] + .first() + .sum() + ) + if cell.any() + else None + ), + } + out["basis"] = ( + "bus stages of the diary sample, each stage a boarding weighted by its " + "trip's weight; fare paid at the point of use = no ticket record and a " + "positive boarding cost; season_or_pass = a non-concessionary ticket " + "record; concessionary_pass = the declared concessionary ticket codes" + ) + return out + + def nts_support_ranges(donor: pd.DataFrame) -> dict[str, tuple[float, float]]: """Per-column donor min/max of the support-clip columns (the E6 bounds input). @@ -604,10 +865,11 @@ def nts_support_ranges(donor: pd.DataFrame) -> dict[str, tuple[float, float]]: """ ranges: dict[str, tuple[float, float]] = { - BAND_COLUMN: (float(NON_USER_BAND), float(MAX_BAND)) + BAND_COLUMN: (float(NON_USER_BAND), float(MAX_BAND)), + SINGLE_FARE_SHARE_COLUMN: (0.0, 1.0), } for column in UK_NTS_SUPPORT_CLIP_COLUMNS: - if column == BAND_COLUMN: + if column in (BAND_COLUMN, SINGLE_FARE_SHARE_COLUMN): continue values = donor[column].to_numpy(dtype=float) ranges[column] = (float(values.min()), float(values.max())) @@ -864,6 +1126,71 @@ def draw_band_from_published_shares( # -------------------------------------------------------------------------- +def single_fare_shares_from_donor( + donor: pd.DataFrame, +) -> tuple[dict[str, dict[str, dict[int, float]]], dict[str, Any]]: + """Share of fare-paying boardings paid at the point of use, per series, group and band. + + Weighted by the diary household weight over the cell's boardings. A cell + with no fare-paying boardings takes its group's all-band share, then the + all-England share, receipted; a series with no fare-paying boardings at + all is refused. + """ + + weights = donor["weight"].to_numpy(dtype=float) + bands = donor[BAND_COLUMN].to_numpy() if BAND_COLUMN in donor else None + groups = donor["residence_group"].to_numpy().astype(str) + shares: dict[str, dict[str, dict[int, float]]] = {} + fallbacks: list[dict[str, object]] = [] + overall: dict[str, float] = {} + for series in SERIES: + paid = donor[boarding_class_column(series, BOARDING_FARE_PAID)].to_numpy( + dtype=float + ) + passes = donor[boarding_class_column(series, BOARDING_PASS)].to_numpy( + dtype=float + ) + + def share( + mask: np.ndarray, paid: np.ndarray = paid, passes: np.ndarray = passes + ) -> float | None: + p = float(np.dot(paid[mask], weights[mask])) + q = float(np.dot(passes[mask], weights[mask])) + return p / (p + q) if p + q > 0 else None + + england = share(np.ones(len(donor), dtype=bool)) + if england is None: + raise NTSBusTravelError( + f"no fare-paying boardings on the {series} series in the donor." + ) + overall[series] = england + shares[series] = {} + for group in RESIDENCE_GROUPS: + in_group = groups == group + group_share = share(in_group) + shares[series][group] = {} + for band in range(len(BAND_IDS)): + cell = in_group & (bands == band) if bands is not None else in_group + value = share(cell) + if value is None: + value = group_share if group_share is not None else england + fallbacks.append({"series": series, "group": group, "band": band}) + shares[series][group][band] = float(value) + receipt = { + "source": "donor_diary_boarding_classes", + "all_england_single_share": overall, + "shares": { + series: { + group: {BAND_IDS[b]: v for b, v in by_band.items()} + for group, by_band in by_group.items() + } + for series, by_group in shares.items() + }, + "cells_filled_from_group_or_england": fallbacks, + } + return shares, receipt + + def band_means_from_donor( donor: pd.DataFrame, ) -> tuple[dict[str, dict[str, dict[int, float]]], dict[str, Any]]: @@ -999,11 +1326,18 @@ def assign_trips_from_band_means( band: np.ndarray, residence_group: np.ndarray, means: Mapping[str, Mapping[str, Mapping[int, float]]], + single_fare_shares: Mapping[str, Mapping[str, Mapping[int, float]]] | None = None, ) -> dict[str, np.ndarray]: - """Each person's annual trips per series from their band and residence group.""" + """Each person's annual trips per series from their band and residence group. + + With ``single_fare_shares`` (per series, group and band) the person's + single-fare share is the trips-weighted combination of the two series' + cell shares; a person with no trips takes the plain mean of the two. + """ out: dict[str, np.ndarray] = {} groups = np.asarray(residence_group).astype(str) + band_index = np.asarray(band) for series in SERIES: values = np.zeros(len(band), dtype=float) for group in RESIDENCE_GROUPS: @@ -1012,12 +1346,30 @@ def assign_trips_from_band_means( [by_band[int(b)] for b in range(len(BAND_IDS))], dtype=float ) mask = groups == group - values[mask] = lookup[np.asarray(band)[mask]] + values[mask] = lookup[band_index[mask]] out[SERIES_TRIP_COLUMNS[series]] = values out[TRIPS_COLUMN] = ( out[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] + out[SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS]] ) + if single_fare_shares is not None: + weighted = np.zeros(len(band), dtype=float) + plain = np.zeros(len(band), dtype=float) + for series in SERIES: + cell_share = np.zeros(len(band), dtype=float) + for group in RESIDENCE_GROUPS: + by_band = single_fare_shares[series][group] + lookup = np.asarray( + [by_band[int(b)] for b in range(len(BAND_IDS))], dtype=float + ) + mask = groups == group + cell_share[mask] = lookup[band_index[mask]] + weighted += out[SERIES_TRIP_COLUMNS[series]] * cell_share + plain += cell_share / len(SERIES) + trips = out[TRIPS_COLUMN] + out[SINGLE_FARE_SHARE_COLUMN] = np.where( + trips > 0, weighted / np.where(trips > 0, trips, 1.0), plain + ) return out @@ -1208,9 +1560,13 @@ class UKNTSBusTravelStageTransform: nts_household_tab_path: str | Path | None = None nts_individual_tab_path: str | Path | None = None nts_trip_tab_path: str | Path | None = None + nts_stage_tab_path: str | Path | None = None + nts_ticket_tab_path: str | Path | None = None nts_household: pd.DataFrame | None = None nts_individual: pd.DataFrame | None = None nts_trip: pd.DataFrame | None = None + nts_stage: pd.DataFrame | None = None + nts_ticket: pd.DataFrame | None = None last_result: UKNTSBusTravelResult | None = field(default=None, init=False) last_fit_weight_records: tuple[FitWeightRecord, ...] | None = field( default=None, init=False @@ -1250,6 +1606,10 @@ def __call__(self, frame: Frame) -> Frame: UK_NTS_INDIVIDUAL_TAB_ROLE, ), self._table(self.nts_trip, self.nts_trip_tab_path, UK_NTS_TRIP_TAB_ROLE), + self._table(self.nts_stage, self.nts_stage_tab_path, UK_NTS_STAGE_TAB_ROLE), + self._table( + self.nts_ticket, self.nts_ticket_tab_path, UK_NTS_TICKET_TAB_ROLE + ), columns=columns, cars_clip=(cars_clip[0], cars_clip[1]), ) @@ -1287,6 +1647,9 @@ def __call__(self, frame: Frame) -> Frame: n_estimators=int(band_parameters.get("n_estimators", 100)), ) means, means_receipt = band_means_from_donor(donor.person) + single_fare_shares, shares_receipt = single_fare_shares_from_donor( + donor.person + ) else: imputation = draw_band_from_published_shares( recipient, @@ -1298,10 +1661,17 @@ def __call__(self, frame: Frame) -> Frame: means, means_receipt = band_means_from_published_rate( self.stage, band_shares=shares ) + single_fare_shares, shares_receipt = single_fare_shares_from_donor( + donor.person + ) band = imputation.band trips = assign_trips_from_band_means( - band, recipient["residence_group"].to_numpy(), means + band, + recipient["residence_group"].to_numpy(), + means, + single_fare_shares=single_fare_shares, ) + means_receipt = {**means_receipt, "single_fare_shares": shares_receipt} rules = eligibility_rules( _operation(self.stage, ASSIGN_BUS_PASS_ELIGIBILITY_KIND) ) @@ -1351,6 +1721,12 @@ def __call__(self, frame: Frame) -> Frame: [BAND_COLUMN, *SERIES_TRIP_COLUMNS.values(), TRIPS_COLUMN] ] ) + donor_support = donor_support.copy() + # The share is a proportion: its donor support is the unit interval, + # which the donor's fare-paying persons span by construction. + donor_support[SINGLE_FARE_SHARE_COLUMN] = np.linspace( + 0.0, 1.0, num=len(donor_support) + ) if TRIPS_COLUMN not in donor_support: donor_support[TRIPS_COLUMN] = ( donor_support[SERIES_TRIP_COLUMNS[BUS_IN_LONDON]] @@ -1370,6 +1746,7 @@ def __call__(self, frame: Frame) -> Frame: SERIES_TRIP_COLUMNS[BUS_IN_LONDON], SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], TRIPS_COLUMN, + SINGLE_FARE_SHARE_COLUMN, ): person[column] = clipped[column].to_numpy(dtype=float) person[ELIGIBLE_COLUMN] = eligible diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py index e1db5069b..7fee0df9b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/terminal_gates.py @@ -229,6 +229,7 @@ def __post_init__(self) -> None: "person.is_parent", "person.is_uc_claimant", "person.legacy_jobseeker_proxy", + "person.local_bus_single_fare_share", "person.local_bus_trips", "person.local_bus_use_band", "person.ons_family_index", diff --git a/packages/microcosm-build/tests/test_uk_consumption_resources.py b/packages/microcosm-build/tests/test_uk_consumption_resources.py index 386780df2..7d6c38df3 100644 --- a/packages/microcosm-build/tests/test_uk_consumption_resources.py +++ b/packages/microcosm-build/tests/test_uk_consumption_resources.py @@ -153,8 +153,16 @@ def test_e6_support_bounds_resources_are_sha_bound_and_non_placeholder() -> None "bus_in_london_trips", "other_local_bus_trips", "local_bus_trips", + "local_bus_single_fare_share", } assert nts["bounds"]["local_bus_use_band"] == [0.0, 6.0] + assert nts["bounds"]["local_bus_single_fare_share"] == [0.0, 1.0] + assert nts["source"]["stage_tab_sha256"] == ( + "4a6015ed54abc32b48e45a5af663d44a39e1147c7ff8c2e087aa29828665b64c" + ) + assert nts["source"]["ticket_tab_sha256"] == ( + "276a99bd30ff4aa3506d2126f6fd269db2f2d0265b5231a55aaefca9212363a0" + ) for column in ("bus_in_london_trips", "other_local_bus_trips", "local_bus_trips"): low, high = nts["bounds"][column] assert low == 0.0 and high > 0.0 diff --git a/packages/microcosm-build/tests/test_uk_frs_spine.py b/packages/microcosm-build/tests/test_uk_frs_spine.py index 8c4b0cf8b..5bcaecf7e 100644 --- a/packages/microcosm-build/tests/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/test_uk_frs_spine.py @@ -2066,6 +2066,8 @@ def test_input_artifact_pins_bind_spi_donor_and_ods() -> None: "nts_household_tab", "nts_individual_tab", "nts_trip_tab", + "nts_stage_tab", + "nts_ticket_tab", "published_fact_surface", "qrf_donor", "was_qrf_donor", diff --git a/packages/microcosm-build/tests/test_uk_graph.py b/packages/microcosm-build/tests/test_uk_graph.py index f6e04fc3d..c487a8c70 100644 --- a/packages/microcosm-build/tests/test_uk_graph.py +++ b/packages/microcosm-build/tests/test_uk_graph.py @@ -233,6 +233,8 @@ def test_uk_production_graph_binds_split_donor_sources_and_runtime_config() -> N "nts_household", "nts_individual", "nts_trip", + "nts_stage", + "nts_ticket", "lcfs_household", "lcfs_person", "etb", diff --git a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py index 9f0b16b80..baa2d43c2 100644 --- a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py +++ b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py @@ -14,6 +14,10 @@ from microcosm.build.uk_runtime.national_frame import uk_national_frame from microcosm.build.uk_runtime.nts_bus_travel import ( BAND_IDS, + BOARDING_CLASSES, + BOARDING_CONCESSIONARY, + BOARDING_FARE_PAID, + BOARDING_PASS, BUS_IN_LONDON, IMPUTE_BUS_USE_BAND_KIND, LONDON_GROUP, @@ -30,6 +34,7 @@ assign_bus_pass_eligibility, assign_trips_from_band_means, band_means_from_donor, + boarding_class_column, clean_nts_travel_tables, eligibility_rules, impute_bus_use_band, @@ -37,6 +42,7 @@ published_car_availability, published_trip_rates, recipient_predictors, + single_fare_shares_from_donor, ) from microcosm.build.uk_runtime.stage_health import uk_stage_health_gate @@ -58,6 +64,15 @@ def _columns() -> NTSColumns: def _synthetic_nts( households: int = 90, *, frequency: bool = True ) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: + household, individual, trip, _stage, _ticket = _synthetic_nts_with_tickets( + households, frequency=frequency + ) + return household, individual, trip + + +def _synthetic_nts_with_tickets( + households: int = 90, *, frequency: bool = True +) -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame]: rows = np.arange(households) household = pd.DataFrame( { @@ -89,17 +104,38 @@ def _synthetic_nts( individual = pd.DataFrame(persons) w2 = dict(zip(household["HouseholdID"], household["W2"], strict=True)) trips = [] + stages = [] + tickets = [] trip_id = 1 + stage_id = 1 + ticket_id = 1 for _, person in individual.iterrows(): code = int(person.get("OrdBus2Freq_B01ID", 10)) count = max(0, 9 - code) london = (int(person["HouseholdID"]) - 1000) % 9 == 6 household_weight = float(w2[int(person["HouseholdID"])]) + pid = int(person["IndividualID"]) + # Odd-numbered households hold a ticket, alternately a concessionary + # pass (7) and a season ticket (1); the rest pay at the point of use, + # with a free boarding every fifth trip. + held = None + hid = int(person["HouseholdID"]) + if hid % 2 == 1: + held = ticket_id + tickets.append( + { + "IndTicketID": ticket_id, + "IndividualID": pid, + "SpecialTicket_B01ID": 7 if (hid // 2) % 2 == 0 else 1, + "SurveyYear": 2024, + } + ) + ticket_id += 1 for t in range(count): trips.append( { "TripID": trip_id, - "IndividualID": int(person["IndividualID"]), + "IndividualID": pid, "HouseholdID": int(person["HouseholdID"]), "MainMode_B04ID": 7 if london else 8, # W5 carries W2 (the household_and_trip basis). @@ -107,6 +143,23 @@ def _synthetic_nts( "JJXSC": 1.0, } ) + free = held is None and t % 5 == 4 + stages.append( + { + "StageID": stage_id, + "TripID": trip_id, + "IndividualID": pid, + "HouseholdID": int(person["HouseholdID"]), + "IndTicketID": held if held is not None else np.nan, + "StageMode_B04ID": 7 if london else 8, + "NumBoardings": 1 + (t % 4 == 3), + "StageFareCost": ( + 0.0 if held is not None or free else 2.0 - (t % 3) * 0.25 + ), + "SurveyYear": 2024, + } + ) + stage_id += 1 trip_id += 1 trips.append( { @@ -119,7 +172,13 @@ def _synthetic_nts( } ) trip_id += 1 - return household, individual, pd.DataFrame(trips) + return ( + household, + individual, + pd.DataFrame(trips), + pd.DataFrame(stages), + pd.DataFrame(tickets), + ) def test_declared_columns_and_codes_parse_from_the_committed_stage() -> None: @@ -196,6 +255,63 @@ def test_cleaning_annualises_diary_trips_per_series_and_maps_the_codebook() -> N ) +def test_stage_and_ticket_tables_class_boardings_and_give_the_single_fare_share() -> ( + None +): + """Fare paid at the point of use, season tickets, concessionary passes, free.""" + + household, individual, trip, stage, ticket = _synthetic_nts_with_tickets() + donor = clean_nts_travel_tables( + household, individual, trip, stage, ticket, columns=_columns() + ) + person = donor.person + assert donor.receipt["ticket_tables_read"] is True + classes = donor.receipt["boarding_classes"] + assert set(classes["by_series"]) == {BUS_IN_LONDON, OTHER_LOCAL_BUS} + for series in (BUS_IN_LONDON, OTHER_LOCAL_BUS): + share = classes["by_series"][series]["single_share_of_fare_paying_boardings"] + assert 0.0 < share < 1.0 + assert classes["by_series"][series]["boardings_per_bus_trip"] >= 1.0 + cell = next(iter(classes["by_group_and_year"].values())) + assert set(cell["boarding_class_shares"]) == set(BOARDING_CLASSES) + assert abs(sum(cell["boarding_class_shares"].values()) - 1.0) < 1e-9 + assert 1.0 <= cell["mean_fare_paid_per_boarding"] <= 2.0 + # Per person: a ticket holder has no fare-paid boardings; a payer has no + # pass boardings; a concessionary holder's boardings are concessionary. + ticket_of = ticket.set_index("IndividualID")["SpecialTicket_B01ID"] + for series in (BUS_IN_LONDON, OTHER_LOCAL_BUS): + paid = person[boarding_class_column(series, BOARDING_FARE_PAID)] + passes = person[boarding_class_column(series, BOARDING_PASS)] + conc = person[boarding_class_column(series, BOARDING_CONCESSIONARY)] + holder = person["individual_id"].map(ticket_of) + assert (paid[holder.notna()] == 0).all() + assert (passes[holder.isna()] == 0).all() and (conc[holder.isna()] == 0).all() + assert (conc[holder == 7] >= 0).all() and (passes[holder == 7] == 0).all() + shares, receipt = single_fare_shares_from_donor(person) + assert set(shares) == {BUS_IN_LONDON, OTHER_LOCAL_BUS} + for series in shares: + for group in shares[series]: + assert all(0.0 <= v <= 1.0 for v in shares[series][group].values()) + assert set(receipt["all_england_single_share"]) == {BUS_IN_LONDON, OTHER_LOCAL_BUS} + trips = assign_trips_from_band_means( + person["local_bus_use_band"].to_numpy(), + person["residence_group"].to_numpy(), + band_means_from_donor(person)[0], + single_fare_shares=shares, + ) + share_column = trips["local_bus_single_fare_share"] + assert share_column.shape == (len(person),) + assert ((share_column >= 0.0) & (share_column <= 1.0)).all() + # Without the tables the donor carries no class columns and the share is absent. + plain = clean_nts_travel_tables(household, individual, trip, columns=_columns()) + assert plain.receipt["ticket_tables_read"] is False + assert boarding_class_column(BUS_IN_LONDON, BOARDING_FARE_PAID) not in plain.person + bad = dict(_operation(_committed_stage(), "clean_nts_travel_tables")) + bad["codes"] = {**bad["codes"], "concessionary_ticket": []} + with pytest.raises(NTSBusTravelError, match="concessionary_ticket"): + NTSColumns.from_parameters(bad) + + def test_cleaning_handles_the_nts_sentinels_and_the_diary_sample() -> None: """-9 is a declared non-user, -8 and unknown age codes drop, W2 = 0 leaves.""" @@ -414,7 +530,7 @@ def test_stage_transform_end_to_end_on_synthetic_inputs() -> None: for op in committed.operations ) stage = dataclasses.replace(committed, operations=operations) - household, individual, trip = _synthetic_nts() + household, individual, trip, nts_stage, nts_ticket = _synthetic_nts_with_tickets() frame, rng = _recipient_frame() transform = UKNTSBusTravelStageTransform( stage=stage, @@ -422,6 +538,8 @@ def test_stage_transform_end_to_end_on_synthetic_inputs() -> None: nts_household=household, nts_individual=individual, nts_trip=trip, + nts_stage=nts_stage, + nts_ticket=nts_ticket, ) result = transform(frame) person = result.table("person") @@ -430,6 +548,7 @@ def test_stage_transform_end_to_end_on_synthetic_inputs() -> None: out_household.columns ) assert person["local_bus_use_band"].between(NON_USER_BAND, MAX_BAND).all() + assert person["local_bus_single_fare_share"].between(0.0, 1.0).all() assert (person["local_bus_trips"] >= 0).all() assert ( person.loc[person["local_bus_use_band"] == NON_USER_BAND, "local_bus_trips"] diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 7a0eaecc7..85125cf1d 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -810,9 +810,10 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: "a7250c519e79e22d366316cd4943f5f4bd2cc86a0e76b919ee2ff2eacb2335f3" "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" "0bb5ca207d76ce6d2be68ba4c0a7dfb982e767165634c15bdb539c921e9edc1f" + "cc7e162b160ae34e2ca81629a7c88dc77edbe36a597636a228db0f496f7d2768" ), "policy_sha256": ( - "11fe34504eecefa7ca584ccecd3c8c6131db71aa2f96f0d6337b2c9fbd55a738" + "a85f9c83fb401d0088b812b7c9a0d05cb067debf973dc0379b50295caf3a4336" ), }, } 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 05c9a7580..68d96eb2f 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 @@ -24,6 +24,8 @@ "lcfs_person": "lcfs_person.csv", "nts_household": "nts_household.csv", "nts_individual": "nts_individual.csv", + "nts_stage": "nts_stage.csv", + "nts_ticket": "nts_ticket.csv", "nts_trip": "nts_trip.csv", "spi_donor": "spi_donor.csv", "was": "was.csv" @@ -3660,6 +3662,30 @@ "size_bytes": 1055711332, "ukds_study_number": 5340 }, + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "stage_eul_2002-2024.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "nts_stage_tab", + "runtime_sha256_required": true, + "sha256": "4a6015ed54abc32b48e45a5af663d44a39e1147c7ff8c2e087aa29828665b64c", + "size_bytes": 1039281193, + "ukds_study_number": 5340 + }, + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-5340-19", + "filename": "ticket_eul_2002-2024.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "nts_ticket_tab", + "runtime_sha256_required": true, + "sha256": "276a99bd30ff4aa3506d2126f6fd269db2f2d0265b5231a55aaefca9212363a0", + "size_bytes": 8655532, + "ukds_study_number": 5340 + }, { "format": "json", "kind": "public_aggregate_reference", @@ -3687,7 +3713,7 @@ "local_bus_trips", "household_local_bus_trips" ], - "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed.", + "notes": "Imputes local-bus travel per person from the National Travel Survey microdata (microcosm#930; the structural fix Maria ruled on 2026-09-15 for the rake-then-bind bus fares of microcosm#890). The donor is the NTS End User Licence extract (England residents only since 2013) pooled over the declared survey years for the conditional fit; the artifact pins are the 19th-edition (November 2025) tabs, verified at runtime, and the H2 fixture drives the stage with synthetic tabs in the same codebook. One QRF target, the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band), conditioned on age band, sex, cars (the was_wealth draw on the recipient), household size, the three-band gross household income and region, drawn from identity-keyed uniforms and rounded to the nearest band; devolved recipients take a declared proxy region for prediction only. Each person's annual local-bus trips are the diary's weighted mean for their band and residence group (London or the rest of England), split into the bus-in-London and other-local-bus series by main mode, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a seven-day diary annualised per person would be right in aggregate and wrong in distribution, so it supplies band means, not per-person counts. If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate (the receipt names the path). Concessionary eligibility is the declared statutory age rule of the person's area, emitted for the lcfs pricing step to zero-price eligible persons' trips; the donor's eligible share of trips per series is receipted beside the publisher's concessionary boarding share. The stage and ticket tables class every diary bus boarding by how it was paid for (at the point of use, a season ticket or pass, a concessionary pass, free) and give each person the share of fare-paying boardings paid at the point of use for their band and residence group (local_bus_single_fare_share), the boardings a per-journey fare cap binds on, with the fare paid per boarding by residence group and survey year receipted beside it (microcosm#930 C13, Mar\u00eda's ask of 2026-09-23). The stage records the frame's band shares against NTS0313/NTS0621, its trips per person against NTS0303 and by age band against NTS0601, and the frame's car availability against NTS0205, all from vendored rows; nothing derived from the licensed rows is committed.", "operations": [ { "age_band_edges": [ @@ -3706,7 +3732,7 @@ 0, 5 ], - "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures).", + "codebook_status": "verified 2026-09-22 against the deposited SN 5340 19th-edition lookup tables and the data extract user guide. Frequency is OrdBus2Freq_B01ID (asked since 2019; OrdBusFreq_B01ID ended in 2018), ten codes folded onto the seven NTS0313 bands (codes 1 to 3 are the three-or-more-times-a-week band, 9 and 10 the less-than-once-a-year-or-never band); code -9 (question not applicable, proxy responses) is declared a non-user because the published NTS0313 shares reproduce only with those persons in the base (2024 at-least-yearly share 0.526 without them, 0.505 with them, the published 0.505); code -8 (no answer) is dropped and receipted. Age_B01ID has 21 bands, each mapped to its lower age and then banded on the declared edges, so donor and recipient share one banding (every NTS band lies inside one declared band). Region codes 10 and 11 (Wales, Scotland) occur only before 2013 and never in the declared years. HHIncome2002_B02ID -8 (no answer) is dropped. The trip weight is W5, which carries the diary household weight W2 (the user guide's trips per person per year is 52.14 x sum(JJXSC x W5) over sum(W2) on the diary sample), so each person's counted trips are divided by W2 before the W2-weighted mean; W5xHH is the within-household factor only. W2 is zero for interview-only households, which leave the donor (the fit and the diary means use the diary sample, as the user guide prescribes for trip measures). Stage and ticket tables, verified 2026-09-23. A stage is a boarding (NumBoardings counts the vehicles), StageMode_B04ID carries the trip-mode categories, StageFareCost is the boarding cost paid at the point of use and IndTicketID links a stage to a held ticket; SpecialTicket_B01ID codes 7 to 11 are the concessionary passes (older people, scholars, disabled persons, subsidised tokens, other concessionary), 1 to 6 non-concessionary season tickets and passes. A boarding with no ticket record and a positive cost paid a single, return or day fare at the point of use; with no record and zero cost it travelled free (children, in the main); with no cost recorded its class is unknown.", "codes": { "age_band": { "1": 0, @@ -3731,6 +3757,13 @@ "8": 18, "9": 19 }, + "concessionary_ticket": [ + 7, + 8, + 9, + 10, + 11 + ], "female": 2, "frequency": { "-9": 0, @@ -3779,7 +3812,16 @@ "region": "HHoldGOR_B02ID", "sex": "Sex_B01ID", "short_walk_multiplier": "JJXSC", + "stage_boardings": "NumBoardings", + "stage_fare_cost": "StageFareCost", + "stage_id": "StageID", + "stage_individual_id": "IndividualID", + "stage_mode": "StageMode_B04ID", + "stage_ticket_id": "IndTicketID", + "stage_trip_id": "TripID", "survey_year": "SurveyYear", + "ticket_id": "IndTicketID", + "ticket_special": "SpecialTicket_B01ID", "trip_id": "TripID", "trip_weight": "W5" }, @@ -3979,6 +4021,7 @@ "other_local_bus_trips", "local_bus_trips", "bus_pass_eligible", + "local_bus_single_fare_share", "household_local_bus_trips" ], "rewrites": [], diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_stage.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_stage.csv new file mode 100644 index 000000000..6d1ebb5f2 --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_stage.csv @@ -0,0 +1,557 @@ +StageID,TripID,IndividualID,HouseholdID,IndTicketID,StageMode_B04ID,NumBoardings,StageFareCost,SurveyYear +1,1,10000,1000,,8,1,2,2024 +2,2,10000,1000,,8,1,1.75,2024 +3,3,10000,1000,,8,1,1.5,2024 +4,4,10000,1000,,8,2,2,2024 +5,5,10000,1000,,8,1,0,2024 +6,6,10000,1000,,8,1,1.5,2024 +7,7,10000,1000,,8,1,2,2024 +8,8,10000,1000,,8,2,1.75,2024 +9,10,10010,1001,1,8,1,0,2024 +10,11,10010,1001,1,8,1,0,2024 +11,12,10010,1001,1,8,1,0,2024 +12,13,10010,1001,1,8,2,0,2024 +13,14,10010,1001,1,8,1,0,2024 +14,15,10010,1001,1,8,1,0,2024 +15,16,10010,1001,1,8,1,0,2024 +16,18,10011,1001,2,8,1,0,2024 +17,19,10011,1001,2,8,1,0,2024 +18,20,10011,1001,2,8,1,0,2024 +19,21,10011,1001,2,8,2,0,2024 +20,22,10011,1001,2,8,1,0,2024 +21,23,10011,1001,2,8,1,0,2024 +22,26,10021,1002,,8,1,2,2024 +23,27,10021,1002,,8,1,1.75,2024 +24,28,10021,1002,,8,1,1.5,2024 +25,29,10021,1002,,8,2,2,2024 +26,30,10021,1002,,8,1,0,2024 +27,32,10022,1002,,8,1,2,2024 +28,33,10022,1002,,8,1,1.75,2024 +29,34,10022,1002,,8,1,1.5,2024 +30,35,10022,1002,,8,2,2,2024 +31,37,10030,1003,3,8,1,0,2024 +32,38,10030,1003,3,8,1,0,2024 +33,39,10030,1003,3,8,1,0,2024 +34,40,10030,1003,3,8,2,0,2024 +35,41,10030,1003,3,8,1,0,2024 +36,44,10032,1003,5,8,1,0,2024 +37,45,10032,1003,5,8,1,0,2024 +38,46,10032,1003,5,8,1,0,2024 +39,48,10033,1003,6,8,1,0,2024 +40,49,10033,1003,6,8,1,0,2024 +41,51,10040,1004,,8,1,2,2024 +42,52,10040,1004,,8,1,1.75,2024 +43,53,10040,1004,,8,1,1.5,2024 +44,54,10040,1004,,8,2,2,2024 +45,56,10050,1005,7,8,1,0,2024 +46,57,10050,1005,7,8,1,0,2024 +47,58,10050,1005,7,8,1,0,2024 +48,60,10051,1005,8,8,1,0,2024 +49,61,10051,1005,8,8,1,0,2024 +50,63,10060,1006,,7,1,2,2024 +51,64,10060,1006,,7,1,1.75,2024 +52,66,10061,1006,,7,1,2,2024 +53,69,10070,1007,9,8,1,0,2024 +54,73,10073,1007,12,8,1,0,2024 +55,74,10073,1007,12,8,1,0,2024 +56,75,10073,1007,12,8,1,0,2024 +57,76,10073,1007,12,8,2,0,2024 +58,77,10073,1007,12,8,1,0,2024 +59,78,10073,1007,12,8,1,0,2024 +60,79,10073,1007,12,8,1,0,2024 +61,80,10073,1007,12,8,2,0,2024 +62,84,10091,1009,14,8,1,0,2024 +63,85,10091,1009,14,8,1,0,2024 +64,86,10091,1009,14,8,1,0,2024 +65,87,10091,1009,14,8,2,0,2024 +66,88,10091,1009,14,8,1,0,2024 +67,89,10091,1009,14,8,1,0,2024 +68,90,10091,1009,14,8,1,0,2024 +69,91,10091,1009,14,8,2,0,2024 +70,93,10100,1010,,8,1,2,2024 +71,94,10100,1010,,8,1,1.75,2024 +72,95,10100,1010,,8,1,1.5,2024 +73,96,10100,1010,,8,2,2,2024 +74,97,10100,1010,,8,1,0,2024 +75,98,10100,1010,,8,1,1.5,2024 +76,99,10100,1010,,8,1,2,2024 +77,100,10100,1010,,8,2,1.75,2024 +78,102,10101,1010,,8,1,2,2024 +79,103,10101,1010,,8,1,1.75,2024 +80,104,10101,1010,,8,1,1.5,2024 +81,105,10101,1010,,8,2,2,2024 +82,106,10101,1010,,8,1,0,2024 +83,107,10101,1010,,8,1,1.5,2024 +84,108,10101,1010,,8,1,2,2024 +85,110,10102,1010,,8,1,2,2024 +86,111,10102,1010,,8,1,1.75,2024 +87,112,10102,1010,,8,1,1.5,2024 +88,113,10102,1010,,8,2,2,2024 +89,114,10102,1010,,8,1,0,2024 +90,115,10102,1010,,8,1,1.5,2024 +91,117,10110,1011,15,8,1,0,2024 +92,118,10110,1011,15,8,1,0,2024 +93,119,10110,1011,15,8,1,0,2024 +94,120,10110,1011,15,8,2,0,2024 +95,121,10110,1011,15,8,1,0,2024 +96,122,10110,1011,15,8,1,0,2024 +97,123,10110,1011,15,8,1,0,2024 +98,125,10111,1011,16,8,1,0,2024 +99,126,10111,1011,16,8,1,0,2024 +100,127,10111,1011,16,8,1,0,2024 +101,128,10111,1011,16,8,2,0,2024 +102,129,10111,1011,16,8,1,0,2024 +103,130,10111,1011,16,8,1,0,2024 +104,132,10112,1011,17,8,1,0,2024 +105,133,10112,1011,17,8,1,0,2024 +106,134,10112,1011,17,8,1,0,2024 +107,135,10112,1011,17,8,2,0,2024 +108,136,10112,1011,17,8,1,0,2024 +109,138,10113,1011,18,8,1,0,2024 +110,139,10113,1011,18,8,1,0,2024 +111,140,10113,1011,18,8,1,0,2024 +112,141,10113,1011,18,8,2,0,2024 +113,143,10120,1012,,8,1,2,2024 +114,144,10120,1012,,8,1,1.75,2024 +115,145,10120,1012,,8,1,1.5,2024 +116,146,10120,1012,,8,2,2,2024 +117,147,10120,1012,,8,1,0,2024 +118,148,10120,1012,,8,1,1.5,2024 +119,151,10131,1013,20,8,1,0,2024 +120,152,10131,1013,20,8,1,0,2024 +121,153,10131,1013,20,8,1,0,2024 +122,154,10131,1013,20,8,2,0,2024 +123,156,10140,1014,,8,1,2,2024 +124,157,10140,1014,,8,1,1.75,2024 +125,158,10140,1014,,8,1,1.5,2024 +126,159,10140,1014,,8,2,2,2024 +127,162,10142,1014,,8,1,2,2024 +128,163,10142,1014,,8,1,1.75,2024 +129,165,10150,1015,21,7,1,0,2024 +130,166,10150,1015,21,7,1,0,2024 +131,167,10150,1015,21,7,1,0,2024 +132,169,10151,1015,22,7,1,0,2024 +133,170,10151,1015,22,7,1,0,2024 +134,174,10160,1016,,8,1,2,2024 +135,175,10160,1016,,8,1,1.75,2024 +136,177,10170,1017,25,8,1,0,2024 +137,182,10182,1018,,8,1,2,2024 +138,183,10182,1018,,8,1,1.75,2024 +139,184,10182,1018,,8,1,1.5,2024 +140,185,10182,1018,,8,2,2,2024 +141,186,10182,1018,,8,1,0,2024 +142,187,10182,1018,,8,1,1.5,2024 +143,188,10182,1018,,8,1,2,2024 +144,189,10182,1018,,8,2,1.75,2024 +145,192,10191,1019,28,8,1,0,2024 +146,193,10191,1019,28,8,1,0,2024 +147,194,10191,1019,28,8,1,0,2024 +148,195,10191,1019,28,8,2,0,2024 +149,196,10191,1019,28,8,1,0,2024 +150,197,10191,1019,28,8,1,0,2024 +151,198,10191,1019,28,8,1,0,2024 +152,199,10191,1019,28,8,2,0,2024 +153,201,10192,1019,29,8,1,0,2024 +154,202,10192,1019,29,8,1,0,2024 +155,203,10192,1019,29,8,1,0,2024 +156,204,10192,1019,29,8,2,0,2024 +157,205,10192,1019,29,8,1,0,2024 +158,206,10192,1019,29,8,1,0,2024 +159,207,10192,1019,29,8,1,0,2024 +160,209,10193,1019,30,8,1,0,2024 +161,210,10193,1019,30,8,1,0,2024 +162,211,10193,1019,30,8,1,0,2024 +163,212,10193,1019,30,8,2,0,2024 +164,213,10193,1019,30,8,1,0,2024 +165,214,10193,1019,30,8,1,0,2024 +166,216,10200,1020,,8,1,2,2024 +167,217,10200,1020,,8,1,1.75,2024 +168,218,10200,1020,,8,1,1.5,2024 +169,219,10200,1020,,8,2,2,2024 +170,220,10200,1020,,8,1,0,2024 +171,221,10200,1020,,8,1,1.5,2024 +172,222,10200,1020,,8,1,2,2024 +173,223,10200,1020,,8,2,1.75,2024 +174,225,10210,1021,31,8,1,0,2024 +175,226,10210,1021,31,8,1,0,2024 +176,227,10210,1021,31,8,1,0,2024 +177,228,10210,1021,31,8,2,0,2024 +178,229,10210,1021,31,8,1,0,2024 +179,230,10210,1021,31,8,1,0,2024 +180,231,10210,1021,31,8,1,0,2024 +181,233,10211,1021,32,8,1,0,2024 +182,234,10211,1021,32,8,1,0,2024 +183,235,10211,1021,32,8,1,0,2024 +184,236,10211,1021,32,8,2,0,2024 +185,237,10211,1021,32,8,1,0,2024 +186,238,10211,1021,32,8,1,0,2024 +187,240,10220,1022,,8,1,2,2024 +188,241,10220,1022,,8,1,1.75,2024 +189,242,10220,1022,,8,1,1.5,2024 +190,243,10220,1022,,8,2,2,2024 +191,244,10220,1022,,8,1,0,2024 +192,245,10220,1022,,8,1,1.5,2024 +193,247,10221,1022,,8,1,2,2024 +194,248,10221,1022,,8,1,1.75,2024 +195,249,10221,1022,,8,1,1.5,2024 +196,250,10221,1022,,8,2,2,2024 +197,251,10221,1022,,8,1,0,2024 +198,253,10222,1022,,8,1,2,2024 +199,254,10222,1022,,8,1,1.75,2024 +200,255,10222,1022,,8,1,1.5,2024 +201,256,10222,1022,,8,2,2,2024 +202,258,10230,1023,33,8,1,0,2024 +203,259,10230,1023,33,8,1,0,2024 +204,260,10230,1023,33,8,1,0,2024 +205,261,10230,1023,33,8,2,0,2024 +206,262,10230,1023,33,8,1,0,2024 +207,264,10231,1023,34,8,1,0,2024 +208,265,10231,1023,34,8,1,0,2024 +209,266,10231,1023,34,8,1,0,2024 +210,267,10231,1023,34,8,2,0,2024 +211,269,10232,1023,35,8,1,0,2024 +212,270,10232,1023,35,8,1,0,2024 +213,271,10232,1023,35,8,1,0,2024 +214,273,10233,1023,36,8,1,0,2024 +215,274,10233,1023,36,8,1,0,2024 +216,277,10250,1025,37,8,1,0,2024 +217,278,10250,1025,37,8,1,0,2024 +218,279,10250,1025,37,8,1,0,2024 +219,282,10260,1026,,8,1,2,2024 +220,283,10260,1026,,8,1,1.75,2024 +221,285,10261,1026,,8,1,2,2024 +222,288,10270,1027,39,8,1,0,2024 +223,295,10291,1029,44,8,1,0,2024 +224,296,10291,1029,44,8,1,0,2024 +225,297,10291,1029,44,8,1,0,2024 +226,298,10291,1029,44,8,2,0,2024 +227,299,10291,1029,44,8,1,0,2024 +228,300,10291,1029,44,8,1,0,2024 +229,301,10291,1029,44,8,1,0,2024 +230,302,10291,1029,44,8,2,0,2024 +231,304,10300,1030,,8,1,2,2024 +232,305,10300,1030,,8,1,1.75,2024 +233,306,10300,1030,,8,1,1.5,2024 +234,307,10300,1030,,8,2,2,2024 +235,308,10300,1030,,8,1,0,2024 +236,309,10300,1030,,8,1,1.5,2024 +237,310,10300,1030,,8,1,2,2024 +238,311,10300,1030,,8,2,1.75,2024 +239,313,10301,1030,,8,1,2,2024 +240,314,10301,1030,,8,1,1.75,2024 +241,315,10301,1030,,8,1,1.5,2024 +242,316,10301,1030,,8,2,2,2024 +243,317,10301,1030,,8,1,0,2024 +244,318,10301,1030,,8,1,1.5,2024 +245,319,10301,1030,,8,1,2,2024 +246,321,10302,1030,,8,1,2,2024 +247,322,10302,1030,,8,1,1.75,2024 +248,323,10302,1030,,8,1,1.5,2024 +249,324,10302,1030,,8,2,2,2024 +250,325,10302,1030,,8,1,0,2024 +251,326,10302,1030,,8,1,1.5,2024 +252,328,10310,1031,45,8,1,0,2024 +253,329,10310,1031,45,8,1,0,2024 +254,330,10310,1031,45,8,1,0,2024 +255,331,10310,1031,45,8,2,0,2024 +256,332,10310,1031,45,8,1,0,2024 +257,333,10310,1031,45,8,1,0,2024 +258,334,10310,1031,45,8,1,0,2024 +259,336,10311,1031,46,8,1,0,2024 +260,337,10311,1031,46,8,1,0,2024 +261,338,10311,1031,46,8,1,0,2024 +262,339,10311,1031,46,8,2,0,2024 +263,340,10311,1031,46,8,1,0,2024 +264,341,10311,1031,46,8,1,0,2024 +265,343,10312,1031,47,8,1,0,2024 +266,344,10312,1031,47,8,1,0,2024 +267,345,10312,1031,47,8,1,0,2024 +268,346,10312,1031,47,8,2,0,2024 +269,347,10312,1031,47,8,1,0,2024 +270,349,10313,1031,48,8,1,0,2024 +271,350,10313,1031,48,8,1,0,2024 +272,351,10313,1031,48,8,1,0,2024 +273,352,10313,1031,48,8,2,0,2024 +274,354,10320,1032,,8,1,2,2024 +275,355,10320,1032,,8,1,1.75,2024 +276,356,10320,1032,,8,1,1.5,2024 +277,357,10320,1032,,8,2,2,2024 +278,358,10320,1032,,8,1,0,2024 +279,359,10320,1032,,8,1,1.5,2024 +280,361,10330,1033,49,7,1,0,2024 +281,362,10330,1033,49,7,1,0,2024 +282,363,10330,1033,49,7,1,0,2024 +283,364,10330,1033,49,7,2,0,2024 +284,365,10330,1033,49,7,1,0,2024 +285,367,10331,1033,50,7,1,0,2024 +286,368,10331,1033,50,7,1,0,2024 +287,369,10331,1033,50,7,1,0,2024 +288,370,10331,1033,50,7,2,0,2024 +289,372,10340,1034,,8,1,2,2024 +290,373,10340,1034,,8,1,1.75,2024 +291,374,10340,1034,,8,1,1.5,2024 +292,375,10340,1034,,8,2,2,2024 +293,377,10341,1034,,8,1,2,2024 +294,378,10341,1034,,8,1,1.75,2024 +295,379,10341,1034,,8,1,1.5,2024 +296,381,10342,1034,,8,1,2,2024 +297,382,10342,1034,,8,1,1.75,2024 +298,385,10351,1035,52,8,1,0,2024 +299,386,10351,1035,52,8,1,0,2024 +300,388,10352,1035,53,8,1,0,2024 +301,391,10360,1036,,8,1,2,2024 +302,392,10360,1036,,8,1,1.75,2024 +303,394,10370,1037,55,8,1,0,2024 +304,399,10382,1038,,8,1,2,2024 +305,400,10382,1038,,8,1,1.75,2024 +306,401,10382,1038,,8,1,1.5,2024 +307,402,10382,1038,,8,2,2,2024 +308,403,10382,1038,,8,1,0,2024 +309,404,10382,1038,,8,1,1.5,2024 +310,405,10382,1038,,8,1,2,2024 +311,406,10382,1038,,8,2,1.75,2024 +312,409,10391,1039,58,8,1,0,2024 +313,410,10391,1039,58,8,1,0,2024 +314,411,10391,1039,58,8,1,0,2024 +315,412,10391,1039,58,8,2,0,2024 +316,413,10391,1039,58,8,1,0,2024 +317,414,10391,1039,58,8,1,0,2024 +318,415,10391,1039,58,8,1,0,2024 +319,416,10391,1039,58,8,2,0,2024 +320,418,10392,1039,59,8,1,0,2024 +321,419,10392,1039,59,8,1,0,2024 +322,420,10392,1039,59,8,1,0,2024 +323,421,10392,1039,59,8,2,0,2024 +324,422,10392,1039,59,8,1,0,2024 +325,423,10392,1039,59,8,1,0,2024 +326,424,10392,1039,59,8,1,0,2024 +327,426,10393,1039,60,8,1,0,2024 +328,427,10393,1039,60,8,1,0,2024 +329,428,10393,1039,60,8,1,0,2024 +330,429,10393,1039,60,8,2,0,2024 +331,430,10393,1039,60,8,1,0,2024 +332,431,10393,1039,60,8,1,0,2024 +333,433,10400,1040,,8,1,2,2024 +334,434,10400,1040,,8,1,1.75,2024 +335,435,10400,1040,,8,1,1.5,2024 +336,436,10400,1040,,8,2,2,2024 +337,437,10400,1040,,8,1,0,2024 +338,438,10400,1040,,8,1,1.5,2024 +339,439,10400,1040,,8,1,2,2024 +340,440,10400,1040,,8,2,1.75,2024 +341,442,10410,1041,61,8,1,0,2024 +342,443,10410,1041,61,8,1,0,2024 +343,444,10410,1041,61,8,1,0,2024 +344,445,10410,1041,61,8,2,0,2024 +345,446,10410,1041,61,8,1,0,2024 +346,447,10410,1041,61,8,1,0,2024 +347,448,10410,1041,61,8,1,0,2024 +348,450,10411,1041,62,8,1,0,2024 +349,451,10411,1041,62,8,1,0,2024 +350,452,10411,1041,62,8,1,0,2024 +351,453,10411,1041,62,8,2,0,2024 +352,454,10411,1041,62,8,1,0,2024 +353,455,10411,1041,62,8,1,0,2024 +354,457,10420,1042,,7,1,2,2024 +355,458,10420,1042,,7,1,1.75,2024 +356,459,10420,1042,,7,1,1.5,2024 +357,460,10420,1042,,7,2,2,2024 +358,461,10420,1042,,7,1,0,2024 +359,462,10420,1042,,7,1,1.5,2024 +360,464,10421,1042,,7,1,2,2024 +361,465,10421,1042,,7,1,1.75,2024 +362,466,10421,1042,,7,1,1.5,2024 +363,467,10421,1042,,7,2,2,2024 +364,468,10421,1042,,7,1,0,2024 +365,470,10422,1042,,7,1,2,2024 +366,471,10422,1042,,7,1,1.75,2024 +367,472,10422,1042,,7,1,1.5,2024 +368,473,10422,1042,,7,2,2,2024 +369,475,10430,1043,63,8,1,0,2024 +370,476,10430,1043,63,8,1,0,2024 +371,477,10430,1043,63,8,1,0,2024 +372,478,10430,1043,63,8,2,0,2024 +373,479,10430,1043,63,8,1,0,2024 +374,481,10431,1043,64,8,1,0,2024 +375,482,10431,1043,64,8,1,0,2024 +376,483,10431,1043,64,8,1,0,2024 +377,484,10431,1043,64,8,2,0,2024 +378,486,10432,1043,65,8,1,0,2024 +379,487,10432,1043,65,8,1,0,2024 +380,488,10432,1043,65,8,1,0,2024 +381,490,10433,1043,66,8,1,0,2024 +382,491,10433,1043,66,8,1,0,2024 +383,493,10440,1044,,8,1,2,2024 +384,494,10440,1044,,8,1,1.75,2024 +385,495,10440,1044,,8,1,1.5,2024 +386,496,10440,1044,,8,2,2,2024 +387,498,10450,1045,67,8,1,0,2024 +388,499,10450,1045,67,8,1,0,2024 +389,500,10450,1045,67,8,1,0,2024 +390,502,10451,1045,68,8,1,0,2024 +391,503,10451,1045,68,8,1,0,2024 +392,506,10461,1046,,8,1,2,2024 +393,509,10470,1047,69,8,1,0,2024 +394,513,10473,1047,72,8,1,0,2024 +395,514,10473,1047,72,8,1,0,2024 +396,515,10473,1047,72,8,1,0,2024 +397,516,10473,1047,72,8,2,0,2024 +398,517,10473,1047,72,8,1,0,2024 +399,518,10473,1047,72,8,1,0,2024 +400,519,10473,1047,72,8,1,0,2024 +401,520,10473,1047,72,8,2,0,2024 +402,524,10491,1049,74,8,1,0,2024 +403,525,10491,1049,74,8,1,0,2024 +404,526,10491,1049,74,8,1,0,2024 +405,527,10491,1049,74,8,2,0,2024 +406,528,10491,1049,74,8,1,0,2024 +407,529,10491,1049,74,8,1,0,2024 +408,530,10491,1049,74,8,1,0,2024 +409,531,10491,1049,74,8,2,0,2024 +410,533,10500,1050,,8,1,2,2024 +411,534,10500,1050,,8,1,1.75,2024 +412,535,10500,1050,,8,1,1.5,2024 +413,536,10500,1050,,8,2,2,2024 +414,537,10500,1050,,8,1,0,2024 +415,538,10500,1050,,8,1,1.5,2024 +416,539,10500,1050,,8,1,2,2024 +417,540,10500,1050,,8,2,1.75,2024 +418,542,10501,1050,,8,1,2,2024 +419,543,10501,1050,,8,1,1.75,2024 +420,544,10501,1050,,8,1,1.5,2024 +421,545,10501,1050,,8,2,2,2024 +422,546,10501,1050,,8,1,0,2024 +423,547,10501,1050,,8,1,1.5,2024 +424,548,10501,1050,,8,1,2,2024 +425,550,10502,1050,,8,1,2,2024 +426,551,10502,1050,,8,1,1.75,2024 +427,552,10502,1050,,8,1,1.5,2024 +428,553,10502,1050,,8,2,2,2024 +429,554,10502,1050,,8,1,0,2024 +430,555,10502,1050,,8,1,1.5,2024 +431,557,10510,1051,75,7,1,0,2024 +432,558,10510,1051,75,7,1,0,2024 +433,559,10510,1051,75,7,1,0,2024 +434,560,10510,1051,75,7,2,0,2024 +435,561,10510,1051,75,7,1,0,2024 +436,562,10510,1051,75,7,1,0,2024 +437,563,10510,1051,75,7,1,0,2024 +438,565,10511,1051,76,7,1,0,2024 +439,566,10511,1051,76,7,1,0,2024 +440,567,10511,1051,76,7,1,0,2024 +441,568,10511,1051,76,7,2,0,2024 +442,569,10511,1051,76,7,1,0,2024 +443,570,10511,1051,76,7,1,0,2024 +444,572,10512,1051,77,7,1,0,2024 +445,573,10512,1051,77,7,1,0,2024 +446,574,10512,1051,77,7,1,0,2024 +447,575,10512,1051,77,7,2,0,2024 +448,576,10512,1051,77,7,1,0,2024 +449,578,10513,1051,78,7,1,0,2024 +450,579,10513,1051,78,7,1,0,2024 +451,580,10513,1051,78,7,1,0,2024 +452,581,10513,1051,78,7,2,0,2024 +453,583,10520,1052,,8,1,2,2024 +454,584,10520,1052,,8,1,1.75,2024 +455,585,10520,1052,,8,1,1.5,2024 +456,586,10520,1052,,8,2,2,2024 +457,587,10520,1052,,8,1,0,2024 +458,588,10520,1052,,8,1,1.5,2024 +459,590,10530,1053,79,8,1,0,2024 +460,591,10530,1053,79,8,1,0,2024 +461,592,10530,1053,79,8,1,0,2024 +462,593,10530,1053,79,8,2,0,2024 +463,594,10530,1053,79,8,1,0,2024 +464,596,10531,1053,80,8,1,0,2024 +465,597,10531,1053,80,8,1,0,2024 +466,598,10531,1053,80,8,1,0,2024 +467,599,10531,1053,80,8,2,0,2024 +468,601,10540,1054,,8,1,2,2024 +469,602,10540,1054,,8,1,1.75,2024 +470,603,10540,1054,,8,1,1.5,2024 +471,604,10540,1054,,8,2,2,2024 +472,606,10541,1054,,8,1,2,2024 +473,607,10541,1054,,8,1,1.75,2024 +474,608,10541,1054,,8,1,1.5,2024 +475,610,10542,1054,,8,1,2,2024 +476,611,10542,1054,,8,1,1.75,2024 +477,613,10550,1055,81,8,1,0,2024 +478,614,10550,1055,81,8,1,0,2024 +479,615,10550,1055,81,8,1,0,2024 +480,617,10551,1055,82,8,1,0,2024 +481,618,10551,1055,82,8,1,0,2024 +482,620,10552,1055,83,8,1,0,2024 +483,623,10560,1056,,8,1,2,2024 +484,624,10560,1056,,8,1,1.75,2024 +485,630,10582,1058,,8,1,2,2024 +486,631,10582,1058,,8,1,1.75,2024 +487,632,10582,1058,,8,1,1.5,2024 +488,633,10582,1058,,8,2,2,2024 +489,634,10582,1058,,8,1,0,2024 +490,635,10582,1058,,8,1,1.5,2024 +491,636,10582,1058,,8,1,2,2024 +492,637,10582,1058,,8,2,1.75,2024 +493,640,10591,1059,88,8,1,0,2024 +494,641,10591,1059,88,8,1,0,2024 +495,642,10591,1059,88,8,1,0,2024 +496,643,10591,1059,88,8,2,0,2024 +497,644,10591,1059,88,8,1,0,2024 +498,645,10591,1059,88,8,1,0,2024 +499,646,10591,1059,88,8,1,0,2024 +500,647,10591,1059,88,8,2,0,2024 +501,650,10593,1059,90,8,1,0,2024 +502,651,10593,1059,90,8,1,0,2024 +503,652,10593,1059,90,8,1,0,2024 +504,653,10593,1059,90,8,2,0,2024 +505,654,10593,1059,90,8,1,0,2024 +506,655,10593,1059,90,8,1,0,2024 +507,657,10600,1060,,7,1,2,2024 +508,658,10600,1060,,7,1,1.75,2024 +509,659,10600,1060,,7,1,1.5,2024 +510,660,10600,1060,,7,2,2,2024 +511,661,10600,1060,,7,1,0,2024 +512,662,10600,1060,,7,1,1.5,2024 +513,663,10600,1060,,7,1,2,2024 +514,664,10600,1060,,7,2,1.75,2024 +515,666,10610,1061,91,8,1,0,2024 +516,667,10610,1061,91,8,1,0,2024 +517,668,10610,1061,91,8,1,0,2024 +518,669,10610,1061,91,8,2,0,2024 +519,670,10610,1061,91,8,1,0,2024 +520,671,10610,1061,91,8,1,0,2024 +521,672,10610,1061,91,8,1,0,2024 +522,674,10611,1061,92,8,1,0,2024 +523,675,10611,1061,92,8,1,0,2024 +524,676,10611,1061,92,8,1,0,2024 +525,677,10611,1061,92,8,2,0,2024 +526,678,10611,1061,92,8,1,0,2024 +527,679,10611,1061,92,8,1,0,2024 +528,681,10620,1062,,8,1,2,2024 +529,682,10620,1062,,8,1,1.75,2024 +530,683,10620,1062,,8,1,1.5,2024 +531,684,10620,1062,,8,2,2,2024 +532,685,10620,1062,,8,1,0,2024 +533,686,10620,1062,,8,1,1.5,2024 +534,688,10621,1062,,8,1,2,2024 +535,689,10621,1062,,8,1,1.75,2024 +536,690,10621,1062,,8,1,1.5,2024 +537,691,10621,1062,,8,2,2,2024 +538,692,10621,1062,,8,1,0,2024 +539,694,10622,1062,,8,1,2,2024 +540,695,10622,1062,,8,1,1.75,2024 +541,696,10622,1062,,8,1,1.5,2024 +542,697,10622,1062,,8,2,2,2024 +543,699,10630,1063,93,8,1,0,2024 +544,700,10630,1063,93,8,1,0,2024 +545,701,10630,1063,93,8,1,0,2024 +546,702,10630,1063,93,8,2,0,2024 +547,703,10630,1063,93,8,1,0,2024 +548,705,10631,1063,94,8,1,0,2024 +549,706,10631,1063,94,8,1,0,2024 +550,707,10631,1063,94,8,1,0,2024 +551,708,10631,1063,94,8,2,0,2024 +552,710,10632,1063,95,8,1,0,2024 +553,711,10632,1063,95,8,1,0,2024 +554,712,10632,1063,95,8,1,0,2024 +555,714,10633,1063,96,8,1,0,2024 +556,715,10633,1063,96,8,1,0,2024 diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_ticket.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_ticket.csv new file mode 100644 index 000000000..ecab46c85 --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/nts_ticket.csv @@ -0,0 +1,97 @@ +IndTicketID,IndividualID,SpecialTicket_B01ID,SurveyYear +1,10010,7,2024 +2,10011,7,2024 +3,10030,1,2024 +4,10031,1,2024 +5,10032,1,2024 +6,10033,1,2024 +7,10050,7,2024 +8,10051,7,2024 +9,10070,1,2024 +10,10071,1,2024 +11,10072,1,2024 +12,10073,1,2024 +13,10090,7,2024 +14,10091,7,2024 +15,10110,1,2024 +16,10111,1,2024 +17,10112,1,2024 +18,10113,1,2024 +19,10130,7,2024 +20,10131,7,2024 +21,10150,1,2024 +22,10151,1,2024 +23,10152,1,2024 +24,10153,1,2024 +25,10170,7,2024 +26,10171,7,2024 +27,10190,1,2024 +28,10191,1,2024 +29,10192,1,2024 +30,10193,1,2024 +31,10210,7,2024 +32,10211,7,2024 +33,10230,1,2024 +34,10231,1,2024 +35,10232,1,2024 +36,10233,1,2024 +37,10250,7,2024 +38,10251,7,2024 +39,10270,1,2024 +40,10271,1,2024 +41,10272,1,2024 +42,10273,1,2024 +43,10290,7,2024 +44,10291,7,2024 +45,10310,1,2024 +46,10311,1,2024 +47,10312,1,2024 +48,10313,1,2024 +49,10330,7,2024 +50,10331,7,2024 +51,10350,1,2024 +52,10351,1,2024 +53,10352,1,2024 +54,10353,1,2024 +55,10370,7,2024 +56,10371,7,2024 +57,10390,1,2024 +58,10391,1,2024 +59,10392,1,2024 +60,10393,1,2024 +61,10410,7,2024 +62,10411,7,2024 +63,10430,1,2024 +64,10431,1,2024 +65,10432,1,2024 +66,10433,1,2024 +67,10450,7,2024 +68,10451,7,2024 +69,10470,1,2024 +70,10471,1,2024 +71,10472,1,2024 +72,10473,1,2024 +73,10490,7,2024 +74,10491,7,2024 +75,10510,1,2024 +76,10511,1,2024 +77,10512,1,2024 +78,10513,1,2024 +79,10530,7,2024 +80,10531,7,2024 +81,10550,1,2024 +82,10551,1,2024 +83,10552,1,2024 +84,10553,1,2024 +85,10570,7,2024 +86,10571,7,2024 +87,10590,1,2024 +88,10591,1,2024 +89,10592,1,2024 +90,10593,1,2024 +91,10610,7,2024 +92,10611,7,2024 +93,10630,1,2024 +94,10631,1,2024 +95,10632,1,2024 +96,10633,1,2024 diff --git a/tools/build_uk_e6_support_bounds.py b/tools/build_uk_e6_support_bounds.py index fcff93e7e..f76a01e72 100644 --- a/tools/build_uk_e6_support_bounds.py +++ b/tools/build_uk_e6_support_bounds.py @@ -106,7 +106,11 @@ def build_etb_services_support_bounds(etb_tab: Path) -> dict[str, object]: def build_nts_support_bounds( - household_tab: Path, individual_tab: Path, trip_tab: Path + household_tab: Path, + individual_tab: Path, + trip_tab: Path, + stage_tab: Path, + ticket_tab: Path, ) -> dict[str, object]: """Bounds of the nts_bus_travel person outputs from the pinned NTS tabs (#930).""" @@ -122,6 +126,8 @@ def build_nts_support_bounds( pd.read_csv(household_tab, sep="\t", low_memory=False), pd.read_csv(individual_tab, sep="\t", low_memory=False), pd.read_csv(trip_tab, sep="\t", low_memory=False), + pd.read_csv(stage_tab, sep="\t", low_memory=False), + pd.read_csv(ticket_tab, sep="\t", low_memory=False), columns=columns, cars_clip=(cars_clip[0], cars_clip[1]), ) @@ -132,6 +138,8 @@ def build_nts_support_bounds( "household_tab_sha256": _sha256(household_tab), "individual_tab_sha256": _sha256(individual_tab), "trip_tab_sha256": _sha256(trip_tab), + "stage_tab_sha256": _sha256(stage_tab), + "ticket_tab_sha256": _sha256(ticket_tab), }, bounds=nts_support_ranges(donor.person), label="NTS bus travel", @@ -146,13 +154,21 @@ def main(argv: list[str] | None = None) -> int: parser.add_argument("--nts-household-tab", type=Path) parser.add_argument("--nts-individual-tab", type=Path) parser.add_argument("--nts-trip-tab", type=Path) + parser.add_argument("--nts-stage-tab", type=Path) + parser.add_argument("--nts-ticket-tab", type=Path) parser.add_argument("--check", action="store_true") args = parser.parse_args(argv) jobs: list[tuple[Path, dict[str, object]]] = [] - nts = (args.nts_household_tab, args.nts_individual_tab, args.nts_trip_tab) + nts = ( + args.nts_household_tab, + args.nts_individual_tab, + args.nts_trip_tab, + args.nts_stage_tab, + args.nts_ticket_tab, + ) if any(nts): if not all(nts): - raise SystemExit("NTS support bounds require all three NTS tabs.") + raise SystemExit("NTS support bounds require all five NTS tabs.") jobs.append( ( UK_PACKAGE / "nts_bus_travel_support_bounds.json", diff --git a/tools/build_uk_frs_spine.py b/tools/build_uk_frs_spine.py index 5e26dfb75..8dc88b8e0 100644 --- a/tools/build_uk_frs_spine.py +++ b/tools/build_uk_frs_spine.py @@ -284,6 +284,16 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: type=Path, help="Caller-supplied private NTS trip tab for nts_bus_travel.", ) + parser.add_argument( + "--nts-stage-tab", + type=Path, + help="Caller-supplied private NTS stage tab for nts_bus_travel.", + ) + parser.add_argument( + "--nts-ticket-tab", + type=Path, + help="Caller-supplied private NTS ticket tab for nts_bus_travel.", + ) parser.add_argument( "--lcfs-hh-tab", type=Path, @@ -340,6 +350,8 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: ("--nts-household-tab", args.nts_household_tab), ("--nts-individual-tab", args.nts_individual_tab), ("--nts-trip-tab", args.nts_trip_tab), + ("--nts-stage-tab", args.nts_stage_tab), + ("--nts-ticket-tab", args.nts_ticket_tab), ("--lcfs-hh-tab", args.lcfs_hh_tab), ("--lcfs-person-tab", args.lcfs_person_tab), ("--etb-tab", args.etb_tab), @@ -445,6 +457,8 @@ def _synthetic_graph_sources(source: Path) -> dict[str, Path]: "nts_household": "nts_household", "nts_individual": "nts_individual", "nts_trip": "nts_trip", + "nts_stage": "nts_stage", + "nts_ticket": "nts_ticket", "lcfs_household": "lcfs_household", "lcfs_person": "lcfs_person", "etb": "etb", @@ -1372,6 +1386,8 @@ def main(argv: list[str] | None = None) -> int: ("--nts-household-tab", args.nts_household_tab), ("--nts-individual-tab", args.nts_individual_tab), ("--nts-trip-tab", args.nts_trip_tab), + ("--nts-stage-tab", args.nts_stage_tab), + ("--nts-ticket-tab", args.nts_ticket_tab), ) if value is None ] @@ -1525,6 +1541,8 @@ def main(argv: list[str] | None = None) -> int: nts_household_tab_path=sources["nts_household"], nts_individual_tab_path=sources["nts_individual"], nts_trip_tab_path=sources["nts_trip"], + nts_stage_tab_path=sources["nts_stage"], + nts_ticket_tab_path=sources["nts_ticket"], ) ) if "regional_property_uprating" in stage_names: @@ -1694,6 +1712,8 @@ def main(argv: list[str] | None = None) -> int: graph_sources["nts_household"] = args.nts_household_tab graph_sources["nts_individual"] = args.nts_individual_tab graph_sources["nts_trip"] = args.nts_trip_tab + graph_sources["nts_stage"] = args.nts_stage_tab + graph_sources["nts_ticket"] = args.nts_ticket_tab if "lcfs_consumption" in stage_names: graph_sources["lcfs_household"] = args.lcfs_hh_tab graph_sources["lcfs_person"] = args.lcfs_person_tab diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index 02805bd54..e5120bd4a 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -671,7 +671,9 @@ def _lcfs_donors() -> tuple[pd.DataFrame, pd.DataFrame]: return pd.DataFrame(household), person -def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: +def _nts_donors() -> tuple[ + pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame, pd.DataFrame +]: """Synthetic NTS Household, Individual and Trip tables (2022-2024). Column names and codes follow the stage's declared codebook (the SN 5340 @@ -720,9 +722,30 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: individual = pd.DataFrame(person_rows) w2_by_household = dict(zip(household["HouseholdID"], household["W2"], strict=True)) trip_rows = [] + stage_rows = [] + ticket_rows = [] trip_id = 1 + stage_id = 1 + ticket_id = 1 for _, person in individual.iterrows(): code = int(person["OrdBus2Freq_B01ID"]) + # Odd-numbered households hold a ticket, alternately a concessionary + # pass (code 7) and a season ticket (code 1); the rest pay at the point + # of use. + held_ticket = None + pid = int(person["IndividualID"]) + hid = int(person["HouseholdID"]) + if hid % 2 == 1: + held_ticket = ticket_id + ticket_rows.append( + { + "IndTicketID": ticket_id, + "IndividualID": pid, + "SpecialTicket_B01ID": 7 if (hid // 2) % 2 == 0 else 1, + "SurveyYear": 2024, + } + ) + ticket_id += 1 # More trips for the frequent codes, none for the never / not-applicable # codes (the NTS0313 bands fold codes 1-3 and 9-10 together). trips = max(0, 9 - code) if 0 < code < 9 else 0 @@ -739,6 +762,27 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: "JJXSC": 1.0, } ) + # One boarding per bus trip, paid at the point of use unless the + # person holds a ticket; a free child boarding every ninth trip. + paid_free = held_ticket is None and t % 5 == 4 + stage_rows.append( + { + "StageID": stage_id, + "TripID": trip_id, + "IndividualID": pid, + "HouseholdID": int(person["HouseholdID"]), + "IndTicketID": held_ticket if held_ticket is not None else "", + "StageMode_B04ID": 7 if london else 8, + "NumBoardings": 1 + (t % 4 == 3), + "StageFareCost": ( + 0.0 + if held_ticket is not None or paid_free + else 2.0 - (t % 3) * 0.25 + ), + "SurveyYear": 2024, + } + ) + stage_id += 1 trip_id += 1 # One non-bus trip per person so the mode filter is exercised. trip_rows.append( @@ -753,7 +797,9 @@ def _nts_donors() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]: ) trip_id += 1 trip = pd.DataFrame(trip_rows) - return household, individual, trip + stage = pd.DataFrame(stage_rows) + ticket = pd.DataFrame(ticket_rows) + return household, individual, trip, stage, ticket def _etb_donor() -> pd.DataFrame: @@ -1198,6 +1244,8 @@ def _build_implementations( nts_household: pd.DataFrame, nts_individual: pd.DataFrame, nts_trip: pd.DataFrame, + nts_stage: pd.DataFrame, + nts_ticket: pd.DataFrame, lcfs_household: pd.DataFrame, lcfs_person: pd.DataFrame, etb: pd.DataFrame, @@ -1271,6 +1319,8 @@ def capture_root(frame: Frame) -> Frame: nts_household=nts_household, nts_individual=nts_individual, nts_trip=nts_trip, + nts_stage=nts_stage, + nts_ticket=nts_ticket, ), "regional_property_uprating": UKRegionalPropertyUpratingStageTransform( stage=stages["regional_property_uprating"] @@ -1417,7 +1467,7 @@ def generate(output: Path) -> None: stage_map = {stage.stage: stage for stage in stages} was = _was_donor() - nts_household, nts_individual, nts_trip = _nts_donors() + nts_household, nts_individual, nts_trip, nts_stage, nts_ticket = _nts_donors() lcfs_household, lcfs_person = _lcfs_donors() etb = _etb_donor() spi_donor = _spi_donor() @@ -1425,6 +1475,8 @@ def generate(output: Path) -> None: _write_csv(sources / "nts_household.csv", nts_household) _write_csv(sources / "nts_individual.csv", nts_individual) _write_csv(sources / "nts_trip.csv", nts_trip) + _write_csv(sources / "nts_stage.csv", nts_stage) + _write_csv(sources / "nts_ticket.csv", nts_ticket) _write_csv(sources / "lcfs_household.csv", lcfs_household) _write_csv(sources / "lcfs_person.csv", lcfs_person) _write_csv(sources / "etb.csv", etb) @@ -1448,6 +1500,8 @@ def generate(output: Path) -> None: nts_household=nts_household, nts_individual=nts_individual, nts_trip=nts_trip, + nts_stage=nts_stage, + nts_ticket=nts_ticket, lcfs_household=lcfs_household, lcfs_person=lcfs_person, etb=etb, @@ -1501,6 +1555,8 @@ def generate(output: Path) -> None: "nts_household": "nts_household.csv", "nts_individual": "nts_individual.csv", "nts_trip": "nts_trip.csv", + "nts_stage": "nts_stage.csv", + "nts_ticket": "nts_ticket.csv", "lcfs_household": "lcfs_household.csv", "lcfs_person": "lcfs_person.csv", "etb": "etb.csv", From 5001cb9f8b85fb4612b166e54041c3c61a7db4b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 12:31:26 +0100 Subject: [PATCH 13/19] =?UTF-8?q?Record=20the=20support=20pricing=20twin,?= =?UTF-8?q?=20the=20single-fare=20share=20readings=20and=20the=20spine-t3?= =?UTF-8?q?=20calibration=20in=20the=20receipts=20(#930=20Parts=20H?= =?UTF-8?q?=E2=80=93J)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 85 ++++++++++++++++++-- 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 7d0d14002..75190be0b 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -305,10 +305,12 @@ sha256 `e6919c04…`, `calibration_diagnostics.json` `e24078e2…`, the frozen 96.55 % of rows within 10 %; ESS 9,231; realised max weight ratio 10.0 (the cap); top-1 % weight share 0.162. The v20 twin on main `ce76b358` (same register, 638 rows): loss 0.3009 → 0.01041, 96.39 % within 10 %, ESS 9,305, top-1 % 0.163. The structural change costs nothing in - fit: loss and the within-10 % share move a hair in #930's favour, ESS 0.8 % against. The eight - rows still beyond 10 % after the solve are the same eight on both (income tax −13 %, VAT +18 %, - CGT liability +10 %, child benefit +19 %, council tax −12 %, ESA −10 %, the two HMRC - self-employment bands +25 % and +18 %): none is a bus row, none moved with #930. + fit: loss and the within-10 % share move a hair in #930's favour, ESS 0.8 % against. 22 rows sit + beyond 10 % after the solve on spine-t and 23 on v20, the same rows but one: v20's CGT gains 25–34 + age band comes inside the fence on spine-t. None is a bus row (income tax −13 %, VAT +18 %, child + benefit +19 %, council tax −12 %, the two HMRC self-employment bands, four state pension bands, ESA + claimants, two UC household rows, the SLC adult dependants' grant, fuel duties on cars and the CGT + age bands make up the rest), and none moved with #930. - Bus rows, design weights → final (the #930 acceptance reading, now a measurement instead of the rake's tautology): England fare receipts (£3,612m, BUS0415-aligned to 2025) −10.9 % → 0.0 % (v20, raked at base year then uprated: −6.1 %); London fare receipts (£1,347m) −21.6 % → +0.1 % @@ -424,5 +426,76 @@ published table fences the share (DfT does not publish boardings by ticket type) receipt line, not a gate. The parameter side, a per-journey cap on the single-fare boardings of fare-paying persons, is policyengine-uk#1871. -spine-t3 (the rebased tree plus C13) and its diff against spine-t2, the calibration and the anatomy -follow below. +spine-t3 (code `bf9f15e1`, the tree rebased onto main `b78f5a88` plus C13, 371 s): 24 of 24 +stage gates; support clip 0 rows clipped on the share (donor range 0 to 1). Design-weighted diary +readings from the stage's receipt (W2 on the diary sample, by residence group and survey year): +London boardings 2024 are 0.42 paid at the point of use, 0.31 on concessionary passes, 0.05 on +season tickets or passes, 0.18 free with no ticket (children under 11 ride free in London), the +single share of fare-paying boardings 0.90 in every year, the fare paid £1.64 mean and £1.75 +median (2022: £1.47 and £1.65); the rest of England moves from 0.32 paid at the point of use, 0.21 +on season tickets and a single share of 0.60 in 2022 to 0.39, 0.14 and 0.74 in 2023 and 0.39, 0.14 +and 0.74 in 2024, the fare paid £1.97 → £1.76 → £1.82 mean, £2.00 median throughout, the diary's +reading of the £2 cap. All-England single share of fare-paying boardings by series: 0.90 (bus in +London), 0.70 (other local bus); per band outside London it runs from 0.86–0.94 in the occasional +bands to 0.61 in the three-or-more-times-a-week band, where the season tickets sit. NTS boardings +per bus trip 1.125 (London series) and 1.121 (other local bus), the same 1.12 the declared +translation gives for England outside London from the publisher's side. No cell fell back. + +Twin diff spine-t2 → spine-t3 (`twin_diff_930_t3.sh`, expectation `spine-t3-payload-expectation.json`): +three observed differences, one expected (`person.local_bus_single_fare_share`, surface +column_only_right, at position 104 of 105), two the structural surfaces the classifier cannot +declare: the person `column_order` (the grown column set) and the root attribute +`populace_mass_log_json`, which differs by exactly the six per-stage household-mass conservation +receipts main's #967 added (WAS, regional uprating, NTS, LCFS, ETB VAT, ETB services, each old and +new total 28,972,433 and factor 1.0). No shared column moves on any entity, `bus_subsidy_spending` +included (the raw-draw rows and the priced rows byte-equal to spine-t2), weights and indices +byte-equal. + +On the frame (spine-t3, design weights, 113,590 persons after the CGT clone): the trip-weighted +single-fare share of fare-paying riders is 0.746 overall, 0.703 in England outside London, 0.901 in +London (the TfL single dominates), 0.688 in Scotland, 0.694 in Wales and 0.672 in Northern Ireland +(the three devolved nations take England's cell shares through their proxy region); per person it +runs from 0.61 (the frequent band outside London) to 1.00. Every person carries positive trips +because the non-user band's diary mean is small but positive (never-users do record the odd +trip), so the share is defined everywhere and the cap's bite on a person is share × fare-paying +boardings × the capped single-fare gap. + +## Part J — national calibration on spine-t3 and the anatomy of the priced support rows (2026-09-23) + +`calibrate_930.sh` on spine-t3 (code `bf9f15e1`, the tree rebased onto main `b78f5a88` with C12 and +C13; artifact `7846605`; the #823 doctrine solve), 463 s, outputs under `calibration-t3/`. + +- The terminal battery blocks at `uk_target_fit`, and not on a bus row: main's #967 register carries + María's signed four-week deferral of `hmrc/self_employment_income_income_band_20_000_to_30_000@2025` + (v20: +25.3 %, just outside the 25 % fence, a calibration-competition regression from the #906/#939 + surface expansion), and on this attempt the row solves to +24.2 %, inside the fence, so the gate + refuses the deferral as stale by design ("stale reviewed target-fit exclusions are back inside the + bound; remove them"). No H5 is written. spine-t's calibration (Part G) ran on the pre-#967 register + and passed; the row solved to +24.6 % there, inside the fence as well. Whether the deferral comes off this branch or main + is María's ruling; the receipts below are read from the Part C sidecars, which the seam writes + before the battery. +- Fit: 643 compiled rows (five more than Part G: #967's additions) on 52,846 records; loss 0.3181 → + 0.01048; 96.73 % within 10 %; ESS 9,033; max ratio 10.0. 21 rows sit beyond 10 % after the + solve against spine-t's 22, the same rows but one (the UC households-with-two-children row comes + inside the fence); none is a bus row, and the self-employment 20–30k band sits at +24.2 %. +- Bus rows, design weights → final. Fares unchanged from Part G: England −10.9 % → 0.0 %, London + −21.6 % → 0.0 %, Scotland +27.8 % → 0.0 %, Northern Ireland +69.6 % → 0.0 %. Support, now priced + from journeys rather than raked: England net support +2.5 % → −0.1 % (Part G's raked column sat at + +4.7 % because the calibration targets are BUS0415-aligned and the rake was at base year), London + +12.8 % → +0.1 % (the value side at 1.158 of the published net support, the frame's eligible + boarding share 0.41 against the publisher's 0.27), Scotland government support +61.8 % → −0.3 % + (1.623: the proxy-region boardings, as for its fares), Wales +5.5 % → 0.0 % (the raw draw). +- Anatomy (`diagnose_uk_target_support.py` on the blocked attempt, thresholds 3× and 5×). Fares: + England 47.9 % of the row's final mass beyond 3× against the frame-wide 47.9 % (Part G: 47.6 % against + 46.6 %), London 56.8 % against 47.9 %, Scotland 14.7 %, Northern Ireland 13.2 %. Support: England net + support 48.6 % against 47.9 % on 37,990 carriers with a top-1 share of 0.4 % (the priced column + reaches every household with a bus rider, where the raked one reached the ETB draw's carriers); + London 50.4 %, Scotland 10.7 % (its carriers are down-weighted, median ratio 0.43, because the + design-weight estimate was 62 % above target), Wales 27.9 %. The frame-wide 47.9 % beyond 3× is the + campaign's property (the 10× cap binds on the same tail as v20), not #930's. + +Reading: retiring the support rake costs nothing in fit (loss 0.01048 on 643 rows against Part G's +0.01036 on 638, the difference being #967's rows), moves the England support row's mass no more than +the frame's, and turns the Scotland support row into the same proxy-region finding as its fares. +The rulings for María stay the two from Part G (the devolved proxy region; the vehicle-share gap) plus +the stale self-employment deferral, which blocks any national line on this tree until it is removed. From 1411562bbda59d827c97565c968b179e309108fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 12:41:55 +0100 Subject: [PATCH 14/19] Write the single-fare share after the eligibility flag, the declared output order the graph's cells use (#930 C13) The H2 parity test caught the stage emitting the two columns in the other order; the fixture is regenerated and the receipts note that spine-t3 was built one commit earlier with the columns swapped, values unchanged. Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 6 ++++++ .../src/microcosm/build/uk_runtime/nts_bus_travel.py | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 75190be0b..deae630f1 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -499,3 +499,9 @@ Reading: retiring the support rake costs nothing in fit (loss 0.01048 on 643 row the frame's, and turns the Scotland support row into the same proxy-region finding as its fares. The rulings for María stay the two from Part G (the devolved proxy region; the vehicle-share gap) plus the stale self-employment deferral, which blocks any national line on this tree until it is removed. + +Post-build fix-up: the C13 sweep's H2 parity test showed the stage writing the share column before the +eligibility flag while the declared outputs (and the graph's cells) put it after; the write order is +aligned and the fixture regenerated (oracle `d7486a5d…`, now equal to the graph's identity). spine-t3 +was built one commit earlier with the two columns in the other order; values, gates, the twin diff and +the calibration are unaffected, and the rebuild is not repeated for a column-order change. diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py index 326c6eb65..3c80499eb 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/nts_bus_travel.py @@ -1746,10 +1746,14 @@ def __call__(self, frame: Frame) -> Frame: SERIES_TRIP_COLUMNS[BUS_IN_LONDON], SERIES_TRIP_COLUMNS[OTHER_LOCAL_BUS], TRIPS_COLUMN, - SINGLE_FARE_SHARE_COLUMN, ): person[column] = clipped[column].to_numpy(dtype=float) person[ELIGIBLE_COLUMN] = eligible + # Declared output order (the graph's cell order): the share follows + # the eligibility flag. + person[SINGLE_FARE_SHARE_COLUMN] = clipped[SINGLE_FARE_SHARE_COLUMN].to_numpy( + dtype=float + ) household = household_table.copy() by_household = ( pd.Series( From 0e5de2ce4971037ea28050fee1d2ac61bff2ee36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 13:10:20 +0100 Subject: [PATCH 15/19] Re-pin the gate and certification digests after rebasing over #971 (#930) Co-Authored-By: Claude Fable 5.1 --- .../microcosm-data/src/microcosm/data/contract.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 85125cf1d..297736e3d 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -803,17 +803,10 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: }, "release_cut": { "gates_manifest_sha256": ( - "9b9623caf02ee37d48cef4ff60171877c94962b0526ee516c89fab253790e8f2" + "22f3d3de05309ae84e211e1f04b11cdeb245ef16ea25f220f903a50028641791" ), "policy_sha256": ( - "77eace424e352172496f8fd99dbf68f858514198f87f6c6a6b33353d7eff55ad" - "a7250c519e79e22d366316cd4943f5f4bd2cc86a0e76b919ee2ff2eacb2335f3" - "b87fa7eb0c1e0281b8a5ab5c7a33509758f1663e4fbbfb467fb970b54e21d84a" - "0bb5ca207d76ce6d2be68ba4c0a7dfb982e767165634c15bdb539c921e9edc1f" - "cc7e162b160ae34e2ca81629a7c88dc77edbe36a597636a228db0f496f7d2768" - ), - "policy_sha256": ( - "a85f9c83fb401d0088b812b7c9a0d05cb067debf973dc0379b50295caf3a4336" + "4da18f48c0f51c90da39c73a332a999c57c6e5e4b7fdd3a1faa40cadfeefb86b" ), }, } From b6ac02075f30a6cbb4e204611b40904b66341d45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 13:52:43 +0100 Subject: [PATCH 16/19] Address Vahid's second pass on #954: Northern Ireland's concession age is 60, under-5s ride free everywhere, stale text retired (#930) The 60+ SmartPass gives free travel on all Translink scheduled services within Northern Ireland from age 60; the 65+ pass adds all-Ireland travel and nothing else, and there is no half-fare tier. The rule is 60, the basis text, the tests, the changelog and the receipts move with it, and the DfI series is described as what it is: the full-fare-concession travel status, the count of free-travel boardings across every concession, not an age series. Under-5s are declared free everywhere (the London and Scotland under-age rules already covered them), so the same law applies in every area instead of being absorbed in three. Also: the receipts' Part D is marked superseded and its stale sentences corrected; the PR body leads with the terminal-battery block and the ruling it needs; the parity test's comment counts 31 stages; the person column order is asserted in the end-to-end test; a zero placeholder pin has a refusal test; dft_bus_journeys.json no longer names the lcfs module as a consumer. Co-Authored-By: Claude Fable 5.1 --- changelog.d/930-nts-bus-travel-stage.added.md | 2 +- experiments/930-nts-bus-journeys-receipts.md | 26 +++++++++----- .../microcosm/build/uk/dft_bus_journeys.json | 1 - .../uk/ledger_fact_vendor_selections.json | 1 - .../src/microcosm/build/uk/source_stages.json | 11 +++--- .../src/microcosm/build/uk/spec/sources.yaml | 7 ++-- .../build/uk_runtime/lcfs_consumption.py | 3 +- .../tests/test_uk_frs_spine.py | 12 +++++++ .../tests/test_uk_nts_bus_travel.py | 36 ++++++++++++++----- .../parity/uk_spine/sources/fixture.json | 7 ++-- .../tests/test_acceptance_h_parity.py | 2 +- 11 files changed, 78 insertions(+), 30 deletions(-) diff --git a/changelog.d/930-nts-bus-travel-stage.added.md b/changelog.d/930-nts-bus-travel-stage.added.md index 196cd4240..c1d58ad1f 100644 --- a/changelog.d/930-nts-bus-travel-stage.added.md +++ b/changelog.d/930-nts-bus-travel-stage.added.md @@ -1 +1 @@ -A person-grain `nts_bus_travel` stage joins the UK spine between `was_wealth` and `lcfs_consumption` (microcosm#930, the structural fix María ruled on 2026-09-15 for microcosm#890's rake-then-bind bus fares). It reads the National Travel Survey microdata (UKDS SN 5340, End User Licence; Household, Individual and Trip tables pinned like the other licensed donors; England residents only since 2013) through a declared codebook (`clean_nts_travel_tables`: column names, region, income-band, sex, main-mode and frequency codes, survey years, banded ages), fits one regime-gated QRF on the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band) conditioned on age band, sex, cars, household size, the three-band gross household income and region (`impute_bus_use_band`, identity-keyed uniforms, rounded to the nearest band, devolved recipients on a declared proxy region), assigns each person the diary's weighted mean annual local-bus trips for their band and residence group split into the bus-in-London and other-local-bus series (`assign_trips_from_band_means`, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a household sum `household_local_bus_trips`), and emits the statutory concessionary eligibility of the person's area (`assign_bus_pass_eligibility`: England outside London at 66, London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 65+). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate, receipted as such. Stage-time gates: a support clip on the band and trips, and `bus_travel_facts`, a population fact check that recomputes the NTS0313 user share and the NTS0303 trips per person from the vendored rows; the frame's car availability against NTS0205 is a receipt line. The artifact pins are placeholders refused at runtime until the licensed tabs land; the H2 fixture drives the stage with synthetic tabs (30 stages), and the graph, kernel registry, spine tool (`--nts-household-tab`, `--nts-individual-tab`, `--nts-trip-tab`), coverage manifest, export surface and gate digests carry the stage. +A person-grain `nts_bus_travel` stage joins the UK spine between `was_wealth` and `lcfs_consumption` (microcosm#930, the structural fix María ruled on 2026-09-15 for microcosm#890's rake-then-bind bus fares). It reads the National Travel Survey microdata (UKDS SN 5340, End User Licence; Household, Individual and Trip tables pinned like the other licensed donors; England residents only since 2013) through a declared codebook (`clean_nts_travel_tables`: column names, region, income-band, sex, main-mode and frequency codes, survey years, banded ages), fits one regime-gated QRF on the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band) conditioned on age band, sex, cars, household size, the three-band gross household income and region (`impute_bus_use_band`, identity-keyed uniforms, rounded to the nearest band, devolved recipients on a declared proxy region), assigns each person the diary's weighted mean annual local-bus trips for their band and residence group split into the bus-in-London and other-local-bus series (`assign_trips_from_band_means`, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a household sum `household_local_bus_trips`), and emits the statutory concessionary eligibility of the person's area (`assign_bus_pass_eligibility`: England outside London at 66, London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 60+, and under-5s free everywhere). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate, receipted as such. Stage-time gates: a support clip on the band and trips, and `bus_travel_facts`, a population fact check that recomputes the NTS0313 user share and the NTS0303 trips per person from the vendored rows; the frame's car availability against NTS0205 is a receipt line. The artifact pins are placeholders refused at runtime until the licensed tabs land; the H2 fixture drives the stage with synthetic tabs (30 stages), and the graph, kernel registry, spine tool (`--nts-household-tab`, `--nts-individual-tab`, `--nts-trip-tab`), coverage manifest, export surface and gate digests carry the stage. diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index deae630f1..054983ce2 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -96,25 +96,32 @@ diagnostics. This is the never-measured #890 acceptance line (England bus-fare m households stretched more than 3x) and #930's measurement, to be read on the first calibration round after the tabs land. -## Part D — the stage, the pricing and the support-side fence (C4–C7, unit-level receipts) +## Part D — the stage, the pricing and the support-side fence (C4–C7, unit-level receipts; superseded) + +Written on 2026-09-18 before the tabs landed. Parts E to K supersede it where they differ: the +artifact pins are real (Part E), the stage count is 33 declared and 31 on the fixture (Part A), the +ETB support rake retired (Part H, `uk_runtime/bus_support_pricing.py` replaced the diagnostic module +named below), and Northern Ireland's concession age is 60 (Part K). Kept as the record of the +declarations as first written. Declarations and runtime, every publisher number reaching the stages through `vendored_rows`: - `nts_bus_travel` (person grain, between `was_wealth` and `lcfs_consumption`; 32 declared - stages, 30 on the H2 fixture): `clean_nts_travel_tables` on the Household, Individual and Trip + stages, 30 on the H2 fixture at the time, 33 and 31 since the rebase): `clean_nts_travel_tables` on the Household, Individual and Trip tabs (UKDS SN 5340, End User Licence; England residents only since 2013) through a declared codebook; one regime-gated QRF on the interview frequency band (`impute_bus_use_band`, identity-keyed uniforms, rounded to the ordinal; devolved recipients on a declared proxy region); `assign_trips_from_band_means` (W5 × JJXSC trips over W2 persons, × 52.14, per band × residence group, split into `bus_in_london_trips` and `other_local_bus_trips`, summed to `household_local_bus_trips`); `assign_bus_pass_eligibility` (England outside London 66+, - London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 65+). If the + London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 65+ as first + declared, 60+ with under-5s free everywhere since Part K). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared midpoints scaled to the vendored NTS0303 rate, receipted. Gates `uk_stage_nts_bus_travel_support` (support clip) and `uk_stage_nts_bus_travel_facts` (`bus_travel_facts`, population fact check: user share within 0.05 of NTS0313, trips per person within 15 % of NTS0303, period 2024); NTS0205 car availability is a receipt line. - The artifact pins are zero placeholders refused at runtime until the tabs land. + The artifact pins were zero placeholders refused at runtime until the tabs landed (Part E). - `lcfs_consumption`: `assign_bus_use_incidence` and the fare cells of `rake_to_vendored_facts` leave the declaration; `price_bus_journeys` (`uk_runtime/bus_fare_pricing.py`) sets `bus_fare_spending` as Σ over the household's non-eligible persons of trips × k × y per @@ -122,12 +129,13 @@ Declarations and runtime, every publisher number reaching the stages through `ve clip precedes it; every other LCFS column is byte-identical on the fixture). Wales keeps the clipped raw draw. Gate `uk_stage_lcfs_consumption_bus_pricing` (`bus_pricing`, population fact check, tolerance 1e-9) recomputes every factor from the vendored rows. -- `etb_services`: the `bus_subsidy_spending` rake stays; gate +- `etb_services` (as first written; the rake retired in Part H): the `bus_subsidy_spending` rake stays; gate `uk_stage_etb_services_support_rake` (`fact_rake`, population fact check) recomputes every cell's published net support through the stage's own declaration, requires the receipt's cells and each cell's design-weighted total after the rake to match (Northern Ireland jointly over bus and rail), and fails closed on a skipped cell; `record_support_per_journey` - (`uk_runtime/bus_support_per_journey.py`) records the value-side alternative, `applied: false`. + (`uk_runtime/bus_support_per_journey.py`, since renamed `bus_support_pricing.py`) records the + value-side alternative, `applied: false`. Factors resolved from the vendored rows at FY2024-25 (`fiscal_start: 2024-04-01`; y = receipts over fare-paying boardings; k = boardings over resident trips, i.e. BUS01 over NTS0705a trips @@ -146,8 +154,10 @@ publisher's concessionary boarding share): covers under-22s since 2022, so its boarding share is twice England's; the eligibility rule matches it). - Northern Ireland (Translink receipts summed over services GBP 150.1m; 67.8m journeys; DfI - full-fare-concession journeys 8.96m, the 65+ SmartPass series, so half-fare 60–64 boardings - are not deducted, declared; proxy rate; population 1.93m): k 1.253, y GBP 2.551, fare per + journeys on the full-fare-concession travel status 8.96m, the count of free-travel boardings + across every concession, not an age series: the only travel status the feed carries (Vahid's + round-one correction; the receipts first called it a 65+ series and inferred a half-fare tier + that does not exist); proxy rate; population 1.93m): k 1.253, y GBP 2.551, fare per trip GBP 3.20, C/B 0.132. - Wales: unpriced (María's ruling); its imputed trips are receipted, not priced. diff --git a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json index ed3cbec36..8e06a6b28 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json +++ b/packages/microcosm-build/src/microcosm/build/uk/dft_bus_journeys.json @@ -5,7 +5,6 @@ "resource": "dft_bus_journeys.json", "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", "consumers": [ - "uk_runtime.lcfs_consumption", "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", "uk_runtime.bus_support_pricing" diff --git a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json index 4b6e267f6..547aa179d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json +++ b/packages/microcosm-build/src/microcosm/build/uk/ledger_fact_vendor_selections.json @@ -586,7 +586,6 @@ "resource": "dft_bus_journeys.json", "purpose": "DfT BUS01 local bus passenger journeys by area (England, London, England outside London, the metropolitan split and the nine English regions; year-ending-March labels 2023 to 2025), the BUS01c elderly and disabled and total concessionary journeys by the same areas, the BUS05i operating revenue and support components beyond fare receipts and net support (concessionary travel reimbursement, Bus Service Operators Grant, gross and net public transport support, total operating revenue, additional funding to operators, fare cap) for England, London and England outside London, and the ONS mid-year population of the four UK countries and the nine English regions (England is the regions' sum). Consumed by the bus fare pricing (receipts over fare-paying boardings, boardings per resident trip) and the support-per-journey diagnostic (microcosm#930).", "consumers": [ - "uk_runtime.lcfs_consumption", "uk_runtime.bus_fare_pricing", "uk_runtime.etb_services", "uk_runtime.bus_support_pricing" 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 49cd97486..5a19d42e0 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -1769,7 +1769,7 @@ { "kind": "assign_bus_pass_eligibility", "output": "bus_pass_eligible", - "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield", + "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland 60+ SmartPass, free on all Translink services within Northern Ireland from age 60, the 65+ pass adding all-Ireland travel only) and under-5s free everywhere; disabled passes and child half-fares are absorbed by the yield", "rules": { "england_outside_london": { "regions": [ @@ -1782,7 +1782,8 @@ "SOUTH_EAST", "SOUTH_WEST" ], - "min_age": 66 + "min_age": 66, + "max_age_exclusive": 5 }, "london": { "regions": [ @@ -1802,13 +1803,15 @@ "regions": [ "WALES" ], - "min_age": 60 + "min_age": 60, + "max_age_exclusive": 5 }, "northern_ireland": { "regions": [ "NORTHERN_IRELAND" ], - "min_age": 65 + "min_age": 60, + "max_age_exclusive": 5 } } }, 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 f9315ede2..757863cbb 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -1351,7 +1351,7 @@ stages: less_than_once_a_year_or_never: 0 - kind: assign_bus_pass_eligibility output: bus_pass_eligible - basis: statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield + basis: statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland 60+ SmartPass, free on all Translink services within Northern Ireland from age 60, the 65+ pass adding all-Ireland travel only) and under-5s free everywhere; disabled passes and child half-fares are absorbed by the yield rules: england_outside_london: regions: @@ -1364,6 +1364,7 @@ stages: - SOUTH_EAST - SOUTH_WEST min_age: 66 + max_age_exclusive: 5 london: regions: - LONDON @@ -1378,10 +1379,12 @@ stages: regions: - WALES min_age: 60 + max_age_exclusive: 5 northern_ireland: regions: - NORTHERN_IRELAND - min_age: 65 + min_age: 60 + max_age_exclusive: 5 - kind: support_clip range: donor_realized - kind: record_mass_conservation_receipt diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py index ba1d23670..31abd752d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/lcfs_consumption.py @@ -154,7 +154,8 @@ UK_LCFS_ROAD_FUEL_RESOURCE = "road_fuel_anchors.json" UK_LCFS_LICENSED_CARS_RESOURCE = "licensed_cars_fuel_type.json" UK_LCFS_DFT_BUS_VALUE_RESOURCE = "dft_bus_value_anchors.json" -# The register names this module as a reader of dft_bus_journeys.json. +# Re-exported for the allowed-resource set; the pricing module is the reader +# the register names. UK_LCFS_DFT_BUS_JOURNEYS_RESOURCE = UK_DFT_BUS_JOURNEYS_RESOURCE UK_LCFS_DEVOLVED_BUS_FINANCE_RESOURCE = "devolved_bus_finance.json" UK_LCFS_VENDORED_RESOURCES = ( diff --git a/packages/microcosm-build/tests/test_uk_frs_spine.py b/packages/microcosm-build/tests/test_uk_frs_spine.py index 5bcaecf7e..3be4ced64 100644 --- a/packages/microcosm-build/tests/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/test_uk_frs_spine.py @@ -2041,6 +2041,18 @@ def test_refuses_sha_mismatch(tmp_path: Path) -> None: build_uk_frs_spine_frame(tmp_path, stage=stage) +def test_read_pinned_tab_refuses_a_zero_placeholder_pin(tmp_path) -> None: + """A 64-zero digest with size 0 (the pre-landing NTS placeholder) never reads.""" + + from microcosm.build.uk_runtime.frs_spine import read_pinned_tab + + tab = tmp_path / "trip_eul_2002-2024.tab" + tab.write_text("TripID\tW5\n1\t1.0\n", encoding="utf-8") + placeholder = {"sha256": "0" * 64, "size_bytes": 0} + with pytest.raises(ValueError, match="not the pinned"): + read_pinned_tab(tab, placeholder) + + def test_refuses_nan_in_produced_weight_column(tmp_path: Path) -> None: tables = _fixture_tables() tables["househol"][0]["GROSS4"] = "" diff --git a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py index baa2d43c2..bc3f6a7e3 100644 --- a/packages/microcosm-build/tests/test_uk_nts_bus_travel.py +++ b/packages/microcosm-build/tests/test_uk_nts_bus_travel.py @@ -27,6 +27,7 @@ REST_OF_ENGLAND_GROUP, SERIES_TRIP_COLUMNS, UK_NTS_BUS_TRAVEL_OUTPUT_COLUMNS, + UK_NTS_PERSON_OUTPUT_COLUMNS, WEEKS_IN_YEAR, NTSBusTravelError, NTSColumns, @@ -481,15 +482,21 @@ def test_eligibility_follows_the_declared_statutory_rules() -> None: "wales", "northern_ireland", } - ages = np.array([10.0, 17.0, 18.0, 21.0, 22.0, 59.0, 60.0, 65.0, 66.0]) + # Under-5s ride free everywhere; Northern Ireland's SmartPass is 60+ (the + # 65+ pass adds all-Ireland travel only); England outside London is State + # Pension age. + ages = np.array([4.0, 10.0, 17.0, 18.0, 21.0, 22.0, 59.0, 60.0, 65.0, 66.0]) for region, expected in ( - ("SOUTH_EAST", [False, False, False, False, False, False, False, False, True]), - ("LONDON", [True, True, False, False, False, False, True, True, True]), - ("SCOTLAND", [True, True, True, True, False, False, True, True, True]), - ("WALES", [False, False, False, False, False, False, True, True, True]), + ( + "SOUTH_EAST", + [True, False, False, False, False, False, False, False, False, True], + ), + ("LONDON", [True, True, True, False, False, False, False, True, True, True]), + ("SCOTLAND", [True, True, True, True, True, False, False, True, True, True]), + ("WALES", [True, False, False, False, False, False, False, True, True, True]), ( "NORTHERN_IRELAND", - [False, False, False, False, False, False, False, True, True], + [True, False, False, False, False, False, False, True, True, True], ), ): eligible, receipt = assign_bus_pass_eligibility( @@ -570,10 +577,21 @@ def test_stage_transform_end_to_end_on_synthetic_inputs() -> None: out_household.set_index("household_id")["region"] ) assert (person.loc[london & (person["age"] < 18), "bus_pass_eligible"]).all() - # Outside London and Scotland no under-60 is eligible (England's rule is - # State Pension age, Wales 60, Northern Ireland 65); Scotland's under-22s are. + # Outside London and Scotland nobody aged 5 to 59 is eligible (England's + # rule is State Pension age, Wales and Northern Ireland 60); under-5s are + # everywhere, and Scotland's under-22s are. plain = region.isin(["SOUTH_EAST", "NORTH_WEST", "WALES", "NORTHERN_IRELAND"]) - assert (~person.loc[plain & (person["age"] < 60), "bus_pass_eligible"]).all() + grown = plain & (person["age"] >= 5) & (person["age"] < 60) + assert (~person.loc[grown, "bus_pass_eligible"]).all() + assert person.loc[person["age"] < 5, "bus_pass_eligible"].all() + assert person.loc[ + region.isin(["WALES", "NORTHERN_IRELAND"]) & (person["age"] >= 60), + "bus_pass_eligible", + ].all() + # The stage's outputs sit at the end of the person table in the declared + # order (the graph's cell order; the H2 parity identity depends on it). + tail = list(person.columns)[-len(UK_NTS_PERSON_OUTPUT_COLUMNS) :] + assert tail == list(UK_NTS_PERSON_OUTPUT_COLUMNS) assert ( person.loc[(region == "SCOTLAND") & (person["age"] < 22), "bus_pass_eligible"] ).all() 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 68d96eb2f..b76ab487e 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 @@ -3958,11 +3958,12 @@ "trip_rates_resource": "nts_trip_rates.json" }, { - "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland SmartPass 65+); disabled passes, under-5s and child fares are absorbed by the yield", + "basis": "statutory concessionary travel by area (ENCTS at State Pension age outside London; London 60+ Oyster and under-18 Zip; Scotland National Entitlement Card 60+ and under-22; Wales 60+; Northern Ireland 60+ SmartPass, free on all Translink services within Northern Ireland from age 60, the 65+ pass adding all-Ireland travel only) and under-5s free everywhere; disabled passes and child half-fares are absorbed by the yield", "kind": "assign_bus_pass_eligibility", "output": "bus_pass_eligible", "rules": { "england_outside_london": { + "max_age_exclusive": 5, "min_age": 66, "regions": [ "NORTH_EAST", @@ -3983,7 +3984,8 @@ ] }, "northern_ireland": { - "min_age": 65, + "max_age_exclusive": 5, + "min_age": 60, "regions": [ "NORTHERN_IRELAND" ] @@ -3996,6 +3998,7 @@ ] }, "wales": { + "max_age_exclusive": 5, "min_age": 60, "regions": [ "WALES" diff --git a/packages/microcosm-graph/tests/test_acceptance_h_parity.py b/packages/microcosm-graph/tests/test_acceptance_h_parity.py index 774ef393a..d253e833b 100644 --- a/packages/microcosm-graph/tests/test_acceptance_h_parity.py +++ b/packages/microcosm-graph/tests/test_acceptance_h_parity.py @@ -280,7 +280,7 @@ def test_h2_uk_spine_parity(tmp_path: Path) -> None: graph = uk_spine_graph() assert graph_from_json((UK_SPINE_PARITY / "uk_spine.json").read_text()) == graph compiled = compile_graph(graph) - assert len(compiled.order) >= 31, "a CREATE node plus the 30 spine stages" + assert len(compiled.order) >= 31, "a CREATE node plus the 31 spine stages" assert all( set(compiled.predecessors[node_id]) <= set(compiled.order[:index]) for index, node_id in enumerate(compiled.order) From e3efb1d60f48eca27373c6cc31bb5f930000796c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 14:10:04 +0100 Subject: [PATCH 17/19] Receipts Part K: spine-t4 calibration and the stretch anatomy after the round-two eligibility change (#930) Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 39 ++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index 054983ce2..d386f2a7b 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -515,3 +515,42 @@ eligibility flag while the declared outputs (and the graph's cells) put it after aligned and the fixture regenerated (oracle `d7486a5d…`, now equal to the graph's identity). spine-t3 was built one commit earlier with the two columns in the other order; values, gates, the twin diff and the calibration are unaffected, and the rebuild is not repeated for a column-order change. + +## Part K — Vahid's second pass: Northern Ireland at 60, under-5s free everywhere (2026-09-23) + +Vahid's round-one should-fix, missed in the first response: nidirect's concessionary travel page has +the 60+ SmartPass giving free travel on all Translink scheduled services within Northern Ireland from +age 60, the 65+ pass adding all-Ireland travel and nothing else, and no half-fare tier. The rule is 60 +(`sources.yaml`, basis text, tests, changelog). The DfI series behind Northern Ireland's C/B is the +full-fare-concession travel status (the count of free-travel boardings across every concession; the +only status the feed carries), not a 65+ series; Part D's sentence is corrected. The child rule is +made uniform at the same time: under-5s ride free everywhere, so England outside London, Wales and +Northern Ireland declare `max_age_exclusive: 5` alongside their age floor instead of absorbing the +under-5s in the yield (London's under-18 and Scotland's under-22 rules already covered them). + +spine-t4 (code `c0d83ba4`, 399 s): 24 of 24 stage gates. Eligible persons 12,689 (Part F: 10,874): +Northern Ireland 1,417 of 3,945 (888), England outside London 6,906 of 22,466 (5,739), Wales 1,126 +of 2,370 (1,007), London and Scotland unchanged. Zero-priced persons 11,563. Design-weight fares +against the bound receipts: England outside London 1.064 (Part F: 1.119; the under-5s' trips no +longer price at the yield), London 0.900 (unchanged), Scotland 1.428 (unchanged), Northern Ireland +1.567 (1.757), the frame's eligible trip share 0.298 beside the publisher's 0.132. Support priced: +England outside London 1.002 of the published net support (Part H: 0.953; the under-5 boardings +now earn the reimbursement), London 1.158 and Scotland 1.623 unchanged. + +Twin diff spine-t3 → spine-t4 (`twin_diff_930_t4.sh`, expectation `spine-t4-payload-expectation.json`): +three observed differences, three expected, none unexpected: `bus_pass_eligible` on the persons the +corrected rules reach, `bus_fare_spending` and the priced `bus_subsidy_spending` on their +households (3,129 priced-support rows; the raw-draw rows byte-equal). Weights, indices and every +other column byte-equal. + +Calibration on spine-t4 (`calibrate_930.sh`, 462 s, `calibration-t4/`): the terminal battery blocks +as on spine-t3, at `uk_target_fit` on the stale self-employment 20–30k deferral (the row solves to ++24.6 %, inside the fence); no H5. From the pre-battery sidecars: 643 rows, loss 0.3173 → 0.01045, +96.73 % within 10 %, ESS 9,036, 21 rows beyond 10 % (the same set as Part J). Bus rows, design +weights → final: England fares −14.0 % → 0.0 % (Part J: −10.9 %; the under-5s' trips left the +priced total), London −21.6 % → 0.0 %, Scotland +27.8 % → −0.1 %, Northern Ireland +49.1 % → 0.0 % +(Part J: +69.6 %; the 60–64s and under-5s now ride free); support England +5.4 % → 0.0 % (+2.5 %), +London +12.8 %, Scotland +61.8 %, Wales +5.5 %, all closed. Anatomy: the England fare row's final +mass beyond 3× is 50.2 % against the frame-wide 48.0 % (Part J: 47.9 % against 47.9 %), London +58.1 %, the England support row 47.8 % against 48.0 %; Northern Ireland's fare row now sits at +9.8 % (its carriers are down-weighted less than before, median ratio 0.50 against 0.47). From b4f8f795ba3d75c73278f9c8ef84f83c192875fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 16:53:54 +0100 Subject: [PATCH 18/19] Rebase onto main 43ca60f6 over #979: fixture and coverage regenerated, digests re-pinned over the union, receipts Part L (#930) Co-Authored-By: Claude Fable 5.1 --- experiments/930-nts-bus-journeys-receipts.md | 16 ++++++ .../uk/release_input_coverage_manifest.json | 56 ++++++++++++++----- .../tests/test_country_spec.py | 6 +- .../microcosm-build/tests/test_uk_graph.py | 11 ++-- .../src/microcosm/data/contract.py | 10 ++-- .../microcosm-data/tests/test_contract.py | 6 +- .../fixtures/parity/uk_spine/PRODUCED_BY.txt | 2 +- .../fixtures/parity/uk_spine/uk_spine.json | 2 +- .../tests/test_acceptance_h_parity.py | 6 +- tools/graph_uk_spine_fixture.py | 2 +- 10 files changed, 78 insertions(+), 39 deletions(-) diff --git a/experiments/930-nts-bus-journeys-receipts.md b/experiments/930-nts-bus-journeys-receipts.md index d386f2a7b..0f28a807c 100644 --- a/experiments/930-nts-bus-journeys-receipts.md +++ b/experiments/930-nts-bus-journeys-receipts.md @@ -554,3 +554,19 @@ London +12.8 %, Scotland +61.8 %, Wales +5.5 %, all closed. Anatomy: the England mass beyond 3× is 50.2 % against the frame-wide 48.0 % (Part J: 47.9 % against 47.9 %), London 58.1 %, the England support row 47.8 % against 48.0 %; Northern Ireland's fare row now sits at 9.8 % (its carriers are down-weighted less than before, median ratio 0.50 against 0.47). + +## Part L — Rebase over #979 (2026-09-23) + +María's ask. Main moved under the branch by #959 and #993 (US-only) and #979 (#970's +`cgt_incidence_anchor` stage, the projection-entrants gate and the incidence-anchor composition +gate). The rebase onto `43ca60f6` stopped nine times, on the regenerated surfaces (coverage +manifest, H2 fixture, contract digests: upstream taken, then regenerated) and on four test files +where both sides added tests or a pending-roster step (both kept). The H2 fixture now carries 32 +stages, 34 declared (oracle identity on this machine `e89af40d…`, reported never pinned); the gate and certification digests are +re-pinned over the union of both PRs' gates; the stage mirror equals the YAML for every stage. The +sweep on the rebased tree (the spine, graph, parity, stage-health, pricing, contract, certification +and #979's own CGT files): 1,118 tests, 0 failures. + +The incidence anchor runs after `hmrc_cgt_asset_type_spine`, downstream of the three bus stages, +so every stage receipt in Parts E–K stands as written; only the terminal weights and a calibration +on the rebased tree would move, and neither is re-run here. 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 53597aed1..e302270c7 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 @@ -473,7 +473,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 2.1a for 2024-25, via the vendored conditioning facts", "survey": "HMRC Capital Gains Tax statistics Table 2.1a (2024-25 individuals) and Advani-Summers capital-gains incidence" @@ -491,7 +491,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -514,7 +514,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -543,7 +543,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -563,7 +563,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -584,7 +584,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -608,10 +608,10 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", - "conditioning_resource_sha256": "f5bb0ad93fff3332b7ae8fb580f002d13207b3f95e44a3103c50108279d94797", + "conditioning_resource_sha256": "d14ef008a05ba9dee2d2922c8bbb8b19e32ac2f6942efd5f0cfc51f62d2cf8aa", "conditioning_surface": "2024-25", "hmrc_surface": "2024-25", "mapped_build_period": "2024" @@ -625,7 +625,7 @@ "base_candidate_tier": "frs", "calibration_permitted": false, "canonical_source_manifest": "source_stages.json", - "canonical_source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "canonical_source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "effective_mass_requirements": { "charitable_investment_gifts": { "mass_share_denominator": "all_person_effective_mass", @@ -708,7 +708,7 @@ "superseded_by": { "reason": "The FRS spine build executes hmrc_spi_income_spine, which supersedes the June retained-leaves/hmrc_spi_income pair inside source_stages.json.", "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "stage": "hmrc_spi_income_spine" } }, @@ -742,7 +742,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -750,6 +750,32 @@ "stage": "lcfs_consumption", "status": "required_at_build" }, + "nts_bus_travel": { + "base_candidate_sha256": "f17306ccb2aad7ff0130be3589b560afb2e2a12a943570911cd0c77f07934833", + "base_candidate_tier": "frs", + "effective_mass_requirements": {}, + "mass_change_semantics": "mass_conserving", + "output_weight_kind": "importance", + "outputs": [ + "local_bus_use_band", + "bus_in_london_trips", + "other_local_bus_trips", + "local_bus_trips", + "bus_pass_eligible", + "local_bus_single_fare_share", + "household_local_bus_trips" + ], + "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": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", + "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" + }, + "stage": "nts_bus_travel", + "status": "required_at_build" + }, "regional_property_uprating": { "base_candidate_sha256": "f17306ccb2aad7ff0130be3589b560afb2e2a12a943570911cd0c77f07934833", "base_candidate_tier": "frs", @@ -763,7 +789,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "source_vintages": { "source": "MHCLG dwellings and ONS UK House Price Index December 2025 regional average prices.", "survey": "Public regional property reference" @@ -787,7 +813,7 @@ "employee_pension_contributions" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -809,7 +835,7 @@ "student_loan_plan" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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" @@ -844,7 +870,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": "7675ceed6aaca930fb7856d37edf8b99d1b8a317b30775125fe20837e1119ec8", + "source_manifest_sha256": "e7d1fb4489982bbeda0b0d6fb554567f4f639c73af35b28a10c619aa06a04797", "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/tests/test_country_spec.py b/packages/microcosm-build/tests/test_country_spec.py index 5c47f1ab1..cec756493 100644 --- a/packages/microcosm-build/tests/test_country_spec.py +++ b/packages/microcosm-build/tests/test_country_spec.py @@ -1000,10 +1000,10 @@ def test_uk_source_manifest_loads_thirty_stages(self) -> None: assert spec.sources is not None # 31 spine stages (uc_reporter_redraw #832, uc_deduction_attributes # #685, frs_relationships #791, hmrc_cgt_asset_type_spine #725, then - # cgt_incidence_anchor #970 as the newest) plus the two certified-pair - # nts_bus_travel #930 as the newest) plus the two certified-pair + # cgt_incidence_anchor #970 and nts_bus_travel #930 as the newest) plus + # the two certified-pair # stages the June path still uses. - assert len(spec.sources.stages) == 33 + assert len(spec.sources.stages) == 34 class TestExistingPackagesGeneralize: diff --git a/packages/microcosm-build/tests/test_uk_graph.py b/packages/microcosm-build/tests/test_uk_graph.py index c487a8c70..91dd51f9a 100644 --- a/packages/microcosm-build/tests/test_uk_graph.py +++ b/packages/microcosm-build/tests/test_uk_graph.py @@ -164,13 +164,10 @@ def test_uk_spine_graph_contains_manifest_stages_and_named_exclusions() -> None: ids = {node.id for node in graph.nodes} # 31 with the #832 uc_reporter_redraw, #685 uc_deduction_attributes, - # #791 frs_relationships, #725 hmrc_cgt_asset_type_spine and #970 - # cgt_incidence_anchor stages; the two named exclusions are the - # certified-pair alternatives, not steps of this pipeline. - # #791 frs_relationships, #725 hmrc_cgt_asset_type_spine and #930 - # nts_bus_travel stages; the two named exclusions are the certified-pair - # alternatives, not steps of this pipeline. - assert len(expected) == 31 + # #791 frs_relationships, #725 hmrc_cgt_asset_type_spine, #970 + # cgt_incidence_anchor and #930 nts_bus_travel stages; the two named + # exclusions are the certified-pair alternatives, not steps of this pipeline. + assert len(expected) == 32 assert UK_SPINE_EXCLUSIONS == { "frs_hmrc_retained_leaves", "hmrc_spi_income", diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 297736e3d..65776ba1f 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 = ( - "1f3980db96a922ced81c89b63daae829f180984b1157a0a73cdc768c1ade7017" + "8757f540a12bdfd65f3466ba4b1bdf31ff29a765bc7caa2b4ca5236c738f843c" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c9141c748dac31d4a0f37d746a8a7639080cf9a80f8cc296aae8e7ef6bafbf79" + "e16c751623fe0bccd1ef5409a60a6a9d9e3d44d1b071a8178314de615b1adb32" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "4e88c60ff7688a8528b793bee666ec669b871899f9d8eae7a6d19eb0b659ddd2" + "86325b18815736f41a2b6d85f468692e721e5131d945635ee9ab0850b14c3266" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -787,10 +787,10 @@ def compatibility_claim_declarer_error(declared_by: object) -> str | None: _UK_CERTIFICATION_PART_DIGESTS: Mapping[str, Mapping[str, str]] = { "spine": { "gates_manifest_sha256": ( - "59b636f960c2a9e4e6cfb7f989949b89c64330bf9f3784d897926e0a9c8dcea3" + "54fe5008caa27a8cc2653b49ac44178ac3f02e973b412b1decac58437d76542f" ), "policy_sha256": ( - "a638c43c4b486962fba6bb6a6ffab557765dce26981b06f066ffdee36616482c" + "6082b3101196c42cd96c272d48cb8a428e0ed9f0355858651505034f507b52d8" ), }, "calibration_seam": { diff --git a/packages/microcosm-data/tests/test_contract.py b/packages/microcosm-data/tests/test_contract.py index 69bdd6c15..f2bc9677c 100644 --- a/packages/microcosm-data/tests/test_contract.py +++ b/packages/microcosm-data/tests/test_contract.py @@ -116,13 +116,13 @@ 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 = ( - "1f3980db96a922ced81c89b63daae829f180984b1157a0a73cdc768c1ade7017" + "8757f540a12bdfd65f3466ba4b1bdf31ff29a765bc7caa2b4ca5236c738f843c" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c9141c748dac31d4a0f37d746a8a7639080cf9a80f8cc296aae8e7ef6bafbf79" + "e16c751623fe0bccd1ef5409a60a6a9d9e3d44d1b071a8178314de615b1adb32" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "4e88c60ff7688a8528b793bee666ec669b871899f9d8eae7a6d19eb0b659ddd2" + "86325b18815736f41a2b6d85f468692e721e5131d945635ee9ab0850b14c3266" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "6f0243bcda09dad26945376230c44ec3cf55d4e417c3a25e29bae8c59bc1a69d" diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/PRODUCED_BY.txt b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/PRODUCED_BY.txt index 3a24f4b36..49fce0258 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/PRODUCED_BY.txt +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/PRODUCED_BY.txt @@ -1 +1 @@ -tools/graph_uk_spine_fixture.py; current 31-transform legacy StagePlan oracle with parsed private-source seams. The acceptance test runs both sides from frs_raw in-process (root weights differ by one ulp between machines); the captured root tables serve the unbound registry's data-only CREATE path. +tools/graph_uk_spine_fixture.py; current 32-transform legacy StagePlan oracle with parsed private-source seams. The acceptance test runs both sides from frs_raw in-process (root weights differ by one ulp between machines); the captured root tables serve the unbound registry's data-only CREATE path. 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 2b14f6ca3..b525de9e1 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":[{"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":{"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},{"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":{"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_relationships","stage_contract_sha256":"30628808d06d9829ebcbcf460cd355a01261e78c7c73e6006c75bec2e3d60c33","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_council_tax","stage_contract_sha256":"3381cd9f7a736514d5073c57480e07f5098890f3ca9ed3865392043594771eb9","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_education","stage_contract_sha256":"836cb0f5a582fee1425190e96c9cb81bdef859bd236c8b6bc27660b6e3d0c2f8","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"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},{"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":{"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_take_up","stage_contract_sha256":"067d31b7fbe733d1d182588705e9ce79df0c8e5f6e8f519314765af49b1b00d7","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_person_draws","stage_contract_sha256":"7e0af955541ec5669dcdf1de4e1e6ca642853e48b775ec4e25238b41491df324","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"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},{"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"],"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.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":{"stage":"was_wealth","stage_contract_sha256":"366e019c41ee2a28bcd61bbaa62a024ed0bb4b30b3ffc4d87ab23b340b4076bf","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"base":"frs_brma.checkpoint","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"],"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","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","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","student_loan_balance"],"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"}],"params":{"stage":"regional_property_uprating","stage_contract_sha256":"acb342e8ca1770556c5682a9411c5ead5d61dd1420cfe6b0305ed14a3407fb25","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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","student_loan_balance"],"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":{"stage":"lcfs_consumption","stage_contract_sha256":"e321f404b2e3a6c0c8bb29861290046db1d4987be071b5c9e3f6fca69a780daf","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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","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","student_loan_balance"],"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":{"stage":"etb_vat","stage_contract_sha256":"5a2b777d88315bcccb72477c088a136c634131e0bc1a339b7287217ee5cfd8d3","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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","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","student_loan_balance"],"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":{"stage":"etb_services","stage_contract_sha256":"a354a6bbf0be88a4001970a0879600511ff83f1194836dafd8c56fc11b31278e","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","employee_pension_contributions","nhs_outpatient_spending"],"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":{"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"2bb3d068003489b47cc8676ac26c203ce3c39a9b6e92f3ecd0a3c06acd6addc4","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"regional_property_uprating.boundary","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","stage":"spi_support_channel","stage_contract_sha256":"4b10f1a4a215cdf2c406c9974de2d1e580eb3cd3a25ed34973c1b63abf4a54bb","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},{"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","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","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index"],"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":{"stage":"hmrc_spi_income_spine","stage_contract_sha256":"4c2edca1f77416a00cff10c7e9d0a9da50e332a2bb6a995ef9ac1bdd00ff97a9","time_period":"2024"},"population":"spi_support_channel","sources":["frs"],"structural":"none","weights":null},{"base":"spi_support_channel","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","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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},{"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","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","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"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","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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},{"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":{"stage":"uc_capital_coherence","stage_contract_sha256":"059f27ee687ee15385b246d43068b17aeecbe3645ccc41fd52fcad06a006a081","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"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":{"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","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","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","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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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.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","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":"Run structural UK stage cgt_band_donors.","id":"cgt_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","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","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","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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_band_donors@1","mass":"free","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_band_donor","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","stage":"cgt_band_donors","stage_contract_sha256":"6fde981ff62f0435f9d708ef4048f64b8edfdec34bab521a19dec677d2603694","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_band_donors.","id":"cgt_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_band_donor"]},"population":"cgt_band_donors","sources":[],"structural":"none","weights":null},{"base":"cgt_band_donors","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","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","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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_capital_gains_clone","household_is_cgt_band_donor"],"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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"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":["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":{"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"f94db1195058327ddd5ddbff93e7510561aaf7773e478d1e76f3e87bbf6f1dfc","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains"],"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_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"529706ff53425e28907eca2451a6d7c8ccb5b0f82643ed62eb3947ed4f71dfc3","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"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","household_is_cgt_band_donor","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","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","stage":"cgt_incidence_anchor","stage_contract_sha256":"00fbe9edc8bd1f31fd79b05cf20b3d5519f9a5b91ded0da35fae1316c1cbb9e0","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"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","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","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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_capital_gains_clone","household_is_cgt_band_donor"],"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","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","student_loan_balance","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","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","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","capital_gains","capital_gains_asset_type","capital_gains_residential_property"],"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"}],"params":{"stage":"salary_sacrifice","stage_contract_sha256":"a4af925af21cc6766eb7c8855b6743a3aa4eeeb38df12cfc83063d7ad6890539","time_period":"2024"},"population":"cgt_incidence_anchor","sources":["frs"],"structural":"none","weights":null},{"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","employee_pension_contributions","highest_education","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":{"stage":"student_loans","stage_contract_sha256":"7c4c76398c2e80b41c7f941a5f06246b57d89b5eb0c36d42e3116ac35e82e203","time_period":"2024"},"population":"cgt_incidence_anchor","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":[{"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":{"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},{"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":{"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_relationships","stage_contract_sha256":"30628808d06d9829ebcbcf460cd355a01261e78c7c73e6006c75bec2e3d60c33","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_council_tax","stage_contract_sha256":"3381cd9f7a736514d5073c57480e07f5098890f3ca9ed3865392043594771eb9","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_education","stage_contract_sha256":"836cb0f5a582fee1425190e96c9cb81bdef859bd236c8b6bc27660b6e3d0c2f8","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"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},{"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":{"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_take_up","stage_contract_sha256":"067d31b7fbe733d1d182588705e9ce79df0c8e5f6e8f519314765af49b1b00d7","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_person_draws","stage_contract_sha256":"7e0af955541ec5669dcdf1de4e1e6ca642853e48b775ec4e25238b41491df324","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"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":{"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},{"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"],"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.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":{"stage":"was_wealth","stage_contract_sha256":"366e019c41ee2a28bcd61bbaa62a024ed0bb4b30b3ffc4d87ab23b340b4076bf","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"base":"frs_brma.checkpoint","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"],"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","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","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","student_loan_balance"],"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"}],"params":{"stage":"regional_property_uprating","stage_contract_sha256":"acb342e8ca1770556c5682a9411c5ead5d61dd1420cfe6b0305ed14a3407fb25","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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","student_loan_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":{"stage":"nts_bus_travel","stage_contract_sha256":"bf4c482b2d6bb848c98c32d24c94d26ebc26e8798e0dddba2e6566a6bd6a6395","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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_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","student_loan_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":{"stage":"lcfs_consumption","stage_contract_sha256":"4b9f3ee0dc3b5788c2694359e69d985bc5f35acb57a75c3a819693c8039cb189","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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_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","student_loan_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":{"stage":"etb_vat","stage_contract_sha256":"5a2b777d88315bcccb72477c088a136c634131e0bc1a339b7287217ee5cfd8d3","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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"],"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","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_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","student_loan_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":{"stage":"etb_services","stage_contract_sha256":"23a4fda91984206cb1183f202d9ac3d48ff914c4e431d098f7a057b15faa9f10","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","employee_pension_contributions","nhs_outpatient_spending"],"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":{"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"2bb3d068003489b47cc8676ac26c203ce3c39a9b6e92f3ecd0a3c06acd6addc4","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"regional_property_uprating.boundary","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","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_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","student_loan_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","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","stage":"spi_support_channel","stage_contract_sha256":"4b10f1a4a215cdf2c406c9974de2d1e580eb3cd3a25ed34973c1b63abf4a54bb","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},{"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","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_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","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","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","student_loan_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","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index"],"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":{"stage":"hmrc_spi_income_spine","stage_contract_sha256":"4c2edca1f77416a00cff10c7e9d0a9da50e332a2bb6a995ef9ac1bdd00ff97a9","time_period":"2024"},"population":"spi_support_channel","sources":["frs"],"structural":"none","weights":null},{"base":"spi_support_channel","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","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_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","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","student_loan_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","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","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},{"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","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_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","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","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","student_loan_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","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","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.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"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","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_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","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","student_loan_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","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","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},{"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":{"stage":"uc_capital_coherence","stage_contract_sha256":"059f27ee687ee15385b246d43068b17aeecbe3645ccc41fd52fcad06a006a081","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"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":{"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","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","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_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","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","student_loan_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","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","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.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","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":"Run structural UK stage cgt_band_donors.","id":"cgt_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","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","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_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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","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","student_loan_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","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","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","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_band_donors@1","mass":"free","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_band_donor","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","stage":"cgt_band_donors","stage_contract_sha256":"f9259f86e38c1c598d31a0967bd7b38c1400b1d5c76f4f974f0dcc3403b1695c","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_band_donors.","id":"cgt_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_band_donor"]},"population":"cgt_band_donors","sources":[],"structural":"none","weights":null},{"base":"cgt_band_donors","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","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_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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_capital_gains_clone","household_is_cgt_band_donor"],"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","student_loan_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","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","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","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"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":["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":{"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"a98e45372baca88a9166be628121f4e3516e69ad87271d7a7e53762d6d8e6e53","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"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":["region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains"],"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_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"33d1c2bd9b5366f39ad690be30f83b3424d275284ed6d2ba9294bd02904376cd","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"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","household_is_cgt_band_donor","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","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","stage":"cgt_incidence_anchor","stage_contract_sha256":"00fbe9edc8bd1f31fd79b05cf20b3d5519f9a5b91ded0da35fae1316c1cbb9e0","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"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","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_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","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_capital_gains_clone","household_is_cgt_band_donor"],"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","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","student_loan_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","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","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","capital_gains","capital_gains_asset_type","capital_gains_residential_property"],"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"}],"params":{"stage":"salary_sacrifice","stage_contract_sha256":"a4af925af21cc6766eb7c8855b6743a3aa4eeeb38df12cfc83063d7ad6890539","time_period":"2024"},"population":"cgt_incidence_anchor","sources":["frs"],"structural":"none","weights":null},{"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","employee_pension_contributions","highest_education","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":{"stage":"student_loans","stage_contract_sha256":"7c4c76398c2e80b41c7f941a5f06246b57d89b5eb0c36d42e3116ac35e82e203","time_period":"2024"},"population":"cgt_incidence_anchor","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/packages/microcosm-graph/tests/test_acceptance_h_parity.py b/packages/microcosm-graph/tests/test_acceptance_h_parity.py index d253e833b..1c264a8b4 100644 --- a/packages/microcosm-graph/tests/test_acceptance_h_parity.py +++ b/packages/microcosm-graph/tests/test_acceptance_h_parity.py @@ -43,7 +43,7 @@ #: was taken under). KERNEL_PARITY = PARITY / "kernels" -#: H2: ``uk_spine.json`` — the 31-stage FRS spine expressed as a graph — plus +#: H2: ``uk_spine.json`` — the 32-stage FRS spine expressed as a graph — plus #: ``sources/``, the data-only bundle both the graph and the legacy oracle #: rebuild their transforms from. The root transform's weights differ at the #: last bit between machines, so both sides recompute the root from the raw @@ -256,7 +256,7 @@ def test_h2_uk_spine_parity(tmp_path: Path) -> None: from declared ``consumes``: the assertion below is that the compiled topological order is derived, so the hand-maintained ``_STAGE_NAMES`` tuple in ``tools/build_uk_frs_spine.py`` — the 30 names intersected with a - 31-stage packaged manifest, kept in step by hand — can be deleted. + 32-stage packaged manifest, kept in step by hand — can be deleted. """ _require(UK_SPINE_PARITY, "the UK migration lane (charter H2, María reviews)") @@ -280,7 +280,7 @@ def test_h2_uk_spine_parity(tmp_path: Path) -> None: graph = uk_spine_graph() assert graph_from_json((UK_SPINE_PARITY / "uk_spine.json").read_text()) == graph compiled = compile_graph(graph) - assert len(compiled.order) >= 31, "a CREATE node plus the 31 spine stages" + assert len(compiled.order) >= 32, "a CREATE node plus the 32 spine stages" assert all( set(compiled.predecessors[node_id]) <= set(compiled.order[:index]) for index, node_id in enumerate(compiled.order) diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index e5120bd4a..617b43023 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -138,7 +138,7 @@ _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 = 31 +UK_FIXTURE_STAGE_COUNT = 32 _QRF_ESTIMATORS = 4 # These are the complete object-string surface observed in the unchanged From 75a1a0f256a4c47787792b72532c91c32d71dbd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 23 Sep 2026 16:55:39 +0100 Subject: [PATCH 19/19] Changelog: the NTS tab pins are real and the fixture has 32 stages (Vahid's third-pass nit, #930) Co-Authored-By: Claude Fable 5.1 --- changelog.d/930-nts-bus-travel-stage.added.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.d/930-nts-bus-travel-stage.added.md b/changelog.d/930-nts-bus-travel-stage.added.md index c1d58ad1f..edef97785 100644 --- a/changelog.d/930-nts-bus-travel-stage.added.md +++ b/changelog.d/930-nts-bus-travel-stage.added.md @@ -1 +1 @@ -A person-grain `nts_bus_travel` stage joins the UK spine between `was_wealth` and `lcfs_consumption` (microcosm#930, the structural fix María ruled on 2026-09-15 for microcosm#890's rake-then-bind bus fares). It reads the National Travel Survey microdata (UKDS SN 5340, End User Licence; Household, Individual and Trip tables pinned like the other licensed donors; England residents only since 2013) through a declared codebook (`clean_nts_travel_tables`: column names, region, income-band, sex, main-mode and frequency codes, survey years, banded ages), fits one regime-gated QRF on the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band) conditioned on age band, sex, cars, household size, the three-band gross household income and region (`impute_bus_use_band`, identity-keyed uniforms, rounded to the nearest band, devolved recipients on a declared proxy region), assigns each person the diary's weighted mean annual local-bus trips for their band and residence group split into the bus-in-London and other-local-bus series (`assign_trips_from_band_means`, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a household sum `household_local_bus_trips`), and emits the statutory concessionary eligibility of the person's area (`assign_bus_pass_eligibility`: England outside London at 66, London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 60+, and under-5s free everywhere). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate, receipted as such. Stage-time gates: a support clip on the band and trips, and `bus_travel_facts`, a population fact check that recomputes the NTS0313 user share and the NTS0303 trips per person from the vendored rows; the frame's car availability against NTS0205 is a receipt line. The artifact pins are placeholders refused at runtime until the licensed tabs land; the H2 fixture drives the stage with synthetic tabs (30 stages), and the graph, kernel registry, spine tool (`--nts-household-tab`, `--nts-individual-tab`, `--nts-trip-tab`), coverage manifest, export surface and gate digests carry the stage. +A person-grain `nts_bus_travel` stage joins the UK spine between `was_wealth` and `lcfs_consumption` (microcosm#930, the structural fix María ruled on 2026-09-15 for microcosm#890's rake-then-bind bus fares). It reads the National Travel Survey microdata (UKDS SN 5340, End User Licence; Household, Individual, Trip, Stage and Ticket tables pinned like the other licensed donors; England residents only since 2013) through a declared codebook (`clean_nts_travel_tables`: column names, region, income-band, sex, main-mode and frequency codes, survey years, banded ages), fits one regime-gated QRF on the interview frequency-of-use band (the variable behind NTS0313; 0 is the non-user band) conditioned on age band, sex, cars, household size, the three-band gross household income and region (`impute_bus_use_band`, identity-keyed uniforms, rounded to the nearest band, devolved recipients on a declared proxy region), assigns each person the diary's weighted mean annual local-bus trips for their band and residence group split into the bus-in-London and other-local-bus series (`assign_trips_from_band_means`, W5 x JJXSC over W2 persons annualised by 52.14 weeks; a household sum `household_local_bus_trips`), and emits the statutory concessionary eligibility of the person's area (`assign_bus_pass_eligibility`: England outside London at 66, London under 18 or 60+, Scotland under 22 or 60+, Wales 60+, Northern Ireland 60+, and under-5s free everywhere). If the extract carries no frequency column the band is drawn from the vendored NTS0313/NTS0621 shares and declared band midpoints are scaled to the vendored NTS0303 rate, receipted as such. Stage-time gates: a support clip on the band and trips, and `bus_travel_facts`, a population fact check that recomputes the NTS0313 user share and the NTS0303 trips per person from the vendored rows; the frame's car availability against NTS0205 is a receipt line. The five tab artifacts are pinned by size and sha256 (a zero placeholder pin is refused at runtime); the H2 fixture drives the stage with synthetic tabs (32 stages), and the graph, kernel registry, spine tool (`--nts-household-tab`, `--nts-individual-tab`, `--nts-trip-tab`, `--nts-stage-tab`, `--nts-ticket-tab`), coverage manifest, export surface and gate digests carry the stage.