From 5bac0d4487b6b2ee553974b3e6e0a3f1f850c4aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:08:23 +0000 Subject: [PATCH 1/7] Add a categorical classifier, held-out scores and keyed donors to microcosm-fit (#1490) Imputing a code (an occupation group, an industry) cannot go through the quantile forest, which interpolates between donor values. microcosm-fit gains three country-agnostic pieces for it: - categorical.CategoricalClassifier: a ConditionalModel for one categorical target under the package's weight contract. It fits a regularised histogram gradient-boosted classifier, a multinomial logit on spline features (arcsinh for long-tailed amounts), or their mixture by boosted_weight (1 and 0 fit one learner), and draws by inverse CDF at caller uniforms (predict_from_uniforms), so a build's keyed uniforms fix each row's draw. It refuses a logit that does not converge, categories it never saw, and non-finite numeric predictors. - held_out: grouped stratified folds and the calibration slope (reusing the sign-gate machinery in qrf), out-of-fold probabilities for the model, each learner and the training folds' class shares, and the scores a stage records (log loss, slope, class-share gaps within strata). - donors: keyed nearest-donor choice within cells, falling back to coarser cells, chosen by weight at the caller's uniform. Refit through this API on FRS 2024-25 coded adults (five household-grouped folds), the blend reproduces the measured one: log loss 1.819 against 1.820, pay-band share gap 0.013, slope 1.01. Co-Authored-By: Claude Opus 5.5 --- .../shared/test_transport_evidence_kernels.py | 6 + .../src/microcosm/fit/__init__.py | 28 + .../src/microcosm/fit/categorical.py | 506 ++++++++++++++++++ .../microcosm-fit/src/microcosm/fit/donors.py | 170 ++++++ .../src/microcosm/fit/held_out.py | 198 +++++++ .../engine_free/shared/test_categorical.py | 222 ++++++++ .../tests/engine_free/shared/test_donors.py | 153 ++++++ .../tests/engine_free/shared/test_held_out.py | 120 +++++ 8 files changed, 1403 insertions(+) create mode 100644 packages/microcosm-fit/src/microcosm/fit/categorical.py create mode 100644 packages/microcosm-fit/src/microcosm/fit/donors.py create mode 100644 packages/microcosm-fit/src/microcosm/fit/held_out.py create mode 100644 packages/microcosm-fit/tests/engine_free/shared/test_categorical.py create mode 100644 packages/microcosm-fit/tests/engine_free/shared/test_donors.py create mode 100644 packages/microcosm-fit/tests/engine_free/shared/test_held_out.py diff --git a/packages/microcosm-build/tests/engine_free/shared/test_transport_evidence_kernels.py b/packages/microcosm-build/tests/engine_free/shared/test_transport_evidence_kernels.py index cb5ab98995..7b290305c7 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_transport_evidence_kernels.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_transport_evidence_kernels.py @@ -137,6 +137,12 @@ [ "microcosm.calibrate.hierarchy_labels", "microcosm.diagnostics.catalogs", + # microcosm#1490: microcosm.fit exports its categorical classifier, + # held-out scores and keyed donors, so a binding that imports the + # package reaches them. + "microcosm.fit.categorical", + "microcosm.fit.donors", + "microcosm.fit.held_out", ] ) BATTERY = "toy.gates.terminal" diff --git a/packages/microcosm-fit/src/microcosm/fit/__init__.py b/packages/microcosm-fit/src/microcosm/fit/__init__.py index 334678386f..982c94a80a 100644 --- a/packages/microcosm-fit/src/microcosm/fit/__init__.py +++ b/packages/microcosm-fit/src/microcosm/fit/__init__.py @@ -73,6 +73,23 @@ def _assert_frame_compatible(version: str, required: tuple[int, int]) -> None: load_fitted_qrf_cache, save_fitted_qrf_cache, ) +from microcosm.fit.categorical import ( # noqa: E402 - after the compatibility gate + BoostedClassifierSettings, + CategoricalClassifier, + FittedCategoricalClassifier, + SplineLogitSettings, + inverse_cdf_draw, +) +from microcosm.fit.donors import ( # noqa: E402 - after the compatibility gate + donor_distance_features, + keyed_nearest_donors, +) +from microcosm.fit.held_out import ( # noqa: E402 - after the compatibility gate + can_deal_folds, + categorical_scores, + out_of_fold_proba, + stratified_folds, +) from microcosm.fit.model import ( # noqa: E402 - after the compatibility gate DESIGN_WEIGHTS, EXPLICIT_WEIGHTS, @@ -162,6 +179,17 @@ def fit( "save_fitted_qrf_cache", "DEFAULT_N_ESTIMATORS", "DEFAULT_ZERO_ATOL", + "CategoricalClassifier", + "FittedCategoricalClassifier", + "BoostedClassifierSettings", + "SplineLogitSettings", + "inverse_cdf_draw", + "stratified_folds", + "can_deal_folds", + "out_of_fold_proba", + "categorical_scores", + "donor_distance_features", + "keyed_nearest_donors", "fit", "__version__", ] diff --git a/packages/microcosm-fit/src/microcosm/fit/categorical.py b/packages/microcosm-fit/src/microcosm/fit/categorical.py new file mode 100644 index 0000000000..f13918ff4d --- /dev/null +++ b/packages/microcosm-fit/src/microcosm/fit/categorical.py @@ -0,0 +1,506 @@ +"""A weighted classifier for one categorical target, drawn at caller uniforms. + +The quantile forest interpolates between donor values, so it cannot impute a +code such as an occupation group or an industry: a draw could fall between two +codes. :class:`CategoricalClassifier` learns ``P(target | predictors)`` for a +single categorical target with a regularised histogram gradient-boosted +classifier, a multinomial logit on spline features, or a weighted average of +the two, and draws one category per row by inverse CDF at a uniform the caller +supplies. A build passes uniforms keyed on stable record identities, so a +row's draw does not depend on which other rows are drawn with it. + +The two learners err in different places. The boosted classifier is sharper +where interactions matter; the logit holds its class shares across margins it +sees only additively and extrapolates more smoothly. Their average is often +better than either, so ``boosted_weight`` sets the mixture: 1 fits only the +boosted classifier, 0 only the logit. + +The fit follows the package's weight contract (:mod:`microcosm.fit.model`): a +Frame fit reads the owning entity's typed weights, a DataFrame fit needs them +stated, and ``weights="none"`` is the only unweighted path. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from dataclasses import dataclass, field +from types import MappingProxyType + +import numpy as np +import pandas as pd +from sklearn.ensemble import HistGradientBoostingClassifier +from sklearn.linear_model import LogisticRegression +from sklearn.preprocessing import SplineTransformer + +from microcosm.fit.model import ( + DESIGN_WEIGHTS, + WeightSpec, + dataframe_fit_columns, + predictors_targets_entity, + resolve_dataframe_fit_weights, + resolve_fit_weights, + resolved_weight_kind, +) +from microcosm.frame import Frame + +__all__ = [ + "BoostedClassifierSettings", + "CategoricalClassifier", + "FittedCategoricalClassifier", + "SplineLogitSettings", + "inverse_cdf_draw", +] + +#: Added to a feature's standard deviation so a constant column scales to zero. +_SCALE_FLOOR = 1e-9 + + +@dataclass(frozen=True) +class BoostedClassifierSettings: + """Settings of the histogram gradient-boosted classifier (scikit-learn's).""" + + learning_rate: float = 0.05 + max_leaf_nodes: int = 15 + min_samples_leaf: int = 40 + l2_regularization: float = 1.0 + early_stopping: bool = True + validation_fraction: float = 0.2 + n_iter_no_change: int = 20 + max_iter: int = 500 + + +@dataclass(frozen=True) +class SplineLogitSettings: + """Settings of the multinomial logit on spline features. + + Each numeric predictor with at least ``n_knots`` distinct training values + is expanded in a B-spline basis (scikit-learn's ``SplineTransformer``); a + predictor with fewer enters as itself. Features are standardised on the + training rows before the weighted L2-penalised fit. + """ + + n_knots: int = 6 + degree: int = 3 + knots: str = "quantile" + extrapolation: str = "constant" + penalty_c: float = 1.0 + solver: str = "lbfgs" + max_iter: int = 3000 + + +def inverse_cdf_draw(proba: np.ndarray, uniforms: np.ndarray) -> np.ndarray: + """The column index each row's uniform falls in, by inverse CDF. + + The cumulative sum's last column is forced to 1, so rounding can never + leave a uniform below 1 without a category. + + Args: + proba: Class probabilities, one row per draw, each row summing to 1. + uniforms: One uniform in ``[0, 1)`` per row. + + Returns: + An int64 array of column indices. + + Raises: + ValueError: If the shapes disagree, a probability is negative or + non-finite, a row does not sum to 1, or a uniform is outside + ``[0, 1)``. + """ + proba = np.asarray(proba, dtype=np.float64) + u = np.asarray(uniforms, dtype=np.float64) + if proba.ndim != 2 or u.shape != (proba.shape[0],): + raise ValueError("inverse_cdf_draw needs one uniform per probability row.") + if not np.isfinite(proba).all() or (proba < 0).any(): + raise ValueError("Class probabilities must be finite and non-negative.") + if not np.allclose(proba.sum(axis=1), 1.0, atol=1e-9): + raise ValueError("Each row of class probabilities must sum to 1.") + if not np.isfinite(u).all() or ((u < 0) | (u >= 1)).any(): + raise ValueError("Draw uniforms must be in [0, 1).") + cumulative = np.cumsum(proba, axis=1) + cumulative[:, -1] = 1.0 + return (cumulative > u[:, None]).argmax(axis=1).astype(np.int64) + + +@dataclass(frozen=True) +class CategoricalClassifier: + """A :class:`~microcosm.fit.model.ConditionalModel` for one categorical target. + + Attributes: + boosted_weight: The boosted classifier's share of the mixture, in + ``[0, 1]``; the logit has the rest. 1 and 0 fit one learner only. + boosted: The boosted classifier's settings. + logit: The spline logit's settings. + categorical_predictors: Predictors entered as categories (one-hot on + their training levels); every other predictor is numeric. + arcsinh_scales: Numeric predictor -> scale. The logit sees + ``arcsinh(x / scale)`` for these before the spline basis, which + tames long-tailed amounts such as incomes. The boosted classifier, + which splits on ranks, always sees the raw values. + seed: Seeds the boosted classifier and the :meth:`predict` draws. + """ + + boosted_weight: float = 0.5 + boosted: BoostedClassifierSettings = BoostedClassifierSettings() + logit: SplineLogitSettings = SplineLogitSettings() + categorical_predictors: tuple[str, ...] = () + arcsinh_scales: Mapping[str, float] = field(default_factory=dict) + seed: int = 0 + + def __post_init__(self) -> None: + weight = float(self.boosted_weight) + if not 0.0 <= weight <= 1.0: + raise ValueError("boosted_weight must be in [0, 1].") + for column, scale in self.arcsinh_scales.items(): + if not np.isfinite(scale) or scale <= 0: + raise ValueError(f"arcsinh scale for {column!r} must be positive.") + object.__setattr__( + self, "categorical_predictors", tuple(self.categorical_predictors) + ) + object.__setattr__( + self, "arcsinh_scales", MappingProxyType(dict(self.arcsinh_scales)) + ) + + def fit( + self, + frame_or_df: Frame | pd.DataFrame, + predictors: list[str], + targets: list[str], + *, + weights: WeightSpec = DESIGN_WEIGHTS, + ) -> FittedCategoricalClassifier: + """Fit ``P(target | predictors)`` for the single categorical target. + + Raises: + ValueError: If there is not exactly one target, a categorical or + arcsinh predictor is not a predictor, the target has a missing + label, a numeric predictor is non-finite, the weights cannot be + resolved, or the logit does not converge. + """ + predictors = list(predictors) + targets = list(targets) + if len(targets) != 1: + raise ValueError("CategoricalClassifier fits exactly one target.") + unknown = [c for c in self.categorical_predictors if c not in predictors] + unknown += [c for c in self.arcsinh_scales if c not in predictors] + if unknown: + raise ValueError( + f"Settings name columns that are not predictors: {unknown}." + ) + if set(self.arcsinh_scales) & set(self.categorical_predictors): + raise ValueError("A categorical predictor cannot take an arcsinh scale.") + + if isinstance(frame_or_df, Frame): + entity = predictors_targets_entity(frame_or_df, predictors, targets) + weight_values = resolve_fit_weights(frame_or_df, entity, weights) + table = frame_or_df.table(entity) + else: + entity = None + dataframe_fit_columns(frame_or_df, predictors, targets) + weight_values = resolve_dataframe_fit_weights( + frame_or_df, weights, predictors=predictors, targets=targets + ) + table = frame_or_df + weight_kind = resolved_weight_kind(frame_or_df, entity, weight_values) + labels = table[targets[0]] + if labels.isna().any(): + raise ValueError(f"Target {targets[0]!r} has rows with no category.") + y = labels.to_numpy() + w = ( + np.ones(len(table)) + if weight_values is None + else np.asarray(weight_values, dtype=np.float64) + ) + features = _Features.fit(table, predictors, self.categorical_predictors) + classes = np.unique(y) + fitted = FittedCategoricalClassifier( + entity=entity, + predictors=predictors, + targets=targets, + classes=classes, + features=features, + boosted_weight=float(self.boosted_weight), + weight_kind=weight_kind, + seed=self.seed, + ) + if len(classes) == 1: + return fitted + if self.boosted_weight > 0: + fitted.boosted_model = self._fit_boosted(features, table, y, w) + if self.boosted_weight < 1: + fitted.logit_model = _SplineLogit.fit( + features, table, y, w, self.logit, self.arcsinh_scales + ) + return fitted + + def _fit_boosted( + self, features: _Features, table: pd.DataFrame, y: np.ndarray, w: np.ndarray + ) -> HistGradientBoostingClassifier: + settings = self.boosted + random_state = int( + np.random.SeedSequence(self.seed).generate_state(1, dtype=np.uint32)[0] + ) + model = HistGradientBoostingClassifier( + learning_rate=settings.learning_rate, + max_leaf_nodes=settings.max_leaf_nodes, + min_samples_leaf=settings.min_samples_leaf, + l2_regularization=settings.l2_regularization, + early_stopping=settings.early_stopping, + validation_fraction=settings.validation_fraction, + n_iter_no_change=settings.n_iter_no_change, + max_iter=settings.max_iter, + random_state=random_state, + ) + return model.fit(features.boosted_matrix(table), y, sample_weight=w) + + +@dataclass +class _Features: + """The numeric and one-hot categorical columns, with the training levels.""" + + numeric: tuple[str, ...] + categorical: tuple[str, ...] + levels: Mapping[str, np.ndarray] + + @classmethod + def fit( + cls, table: pd.DataFrame, predictors: list[str], categorical: Sequence[str] + ) -> _Features: + numeric = tuple(c for c in predictors if c not in categorical) + features = cls( + numeric=numeric, + categorical=tuple(c for c in predictors if c in categorical), + levels={}, + ) + features.numeric_values(table) + features.levels = { + column: np.unique(table[column].to_numpy()) + for column in features.categorical + } + return features + + def numeric_values(self, table: pd.DataFrame) -> np.ndarray: + values = table.loc[:, list(self.numeric)].to_numpy(dtype=np.float64) + if not np.isfinite(values).all(): + bad = [ + column + for column, ok in zip( + self.numeric, np.isfinite(values).all(axis=0), strict=True + ) + if not ok + ] + raise ValueError(f"Numeric predictors have non-finite values: {bad}.") + return values + + def one_hot(self, table: pd.DataFrame) -> np.ndarray: + parts = [] + for column in self.categorical: + values = table[column].to_numpy() + known = self.levels[column] + unseen = sorted({str(v) for v in values} - {str(v) for v in known}) + if unseen: + raise ValueError( + f"Predictor {column!r} has categories the fit never saw: {unseen}." + ) + parts.append((values[:, None] == known[None, :]).astype(np.float64)) + if not parts: + return np.zeros((len(table), 0)) + return np.hstack(parts) + + def boosted_matrix(self, table: pd.DataFrame) -> np.ndarray: + return np.hstack([self.numeric_values(table), self.one_hot(table)]) + + +@dataclass +class _SplineLogit: + """The fitted spline basis, scaling and multinomial logit.""" + + transformers: Mapping[str, SplineTransformer | None] + arcsinh_scales: Mapping[str, float] + mean: np.ndarray + scale: np.ndarray + model: LogisticRegression + + @classmethod + def fit( + cls, + features: _Features, + table: pd.DataFrame, + y: np.ndarray, + w: np.ndarray, + settings: SplineLogitSettings, + arcsinh_scales: Mapping[str, float], + ) -> _SplineLogit: + transformed = cls._transformed(features, table, arcsinh_scales) + transformers: dict[str, SplineTransformer | None] = {} + for index, column in enumerate(features.numeric): + values = transformed[:, [index]] + if len(np.unique(values)) < settings.n_knots: + transformers[column] = None + continue + transformers[column] = SplineTransformer( + n_knots=settings.n_knots, + degree=settings.degree, + knots=settings.knots, + extrapolation=settings.extrapolation, + ).fit(values) + logit = cls( + transformers=transformers, + arcsinh_scales=arcsinh_scales, + mean=np.zeros(0), + scale=np.ones(0), + model=LogisticRegression( + C=settings.penalty_c, solver=settings.solver, max_iter=settings.max_iter + ), + ) + raw = logit._expanded(features, table) + logit.mean = raw.mean(axis=0) + logit.scale = raw.std(axis=0) + _SCALE_FLOOR + logit.model.fit((raw - logit.mean) / logit.scale, y, sample_weight=w / w.mean()) + if int(np.max(logit.model.n_iter_)) >= settings.max_iter: + raise ValueError( + f"The spline logit did not converge in {settings.max_iter} " + "iterations; raise max_iter or check the predictors." + ) + return logit + + @staticmethod + def _transformed( + features: _Features, table: pd.DataFrame, arcsinh_scales: Mapping[str, float] + ) -> np.ndarray: + values = features.numeric_values(table).copy() + for index, column in enumerate(features.numeric): + if column in arcsinh_scales: + values[:, index] = np.arcsinh(values[:, index] / arcsinh_scales[column]) + return values + + def _expanded(self, features: _Features, table: pd.DataFrame) -> np.ndarray: + transformed = self._transformed(features, table, self.arcsinh_scales) + parts = [] + for index, column in enumerate(features.numeric): + transformer = self.transformers[column] + values = transformed[:, [index]] + parts.append( + values if transformer is None else transformer.transform(values) + ) + parts.append(features.one_hot(table)) + return np.hstack(parts) + + def predict_proba(self, features: _Features, table: pd.DataFrame) -> np.ndarray: + raw = self._expanded(features, table) + return self.model.predict_proba((raw - self.mean) / self.scale) + + @property + def iterations(self) -> int: + return int(np.max(self.model.n_iter_)) + + +class FittedCategoricalClassifier: + """A fitted :class:`CategoricalClassifier`, ready to give probabilities and draws. + + Attributes: + entity: The entity the predictors and target live on, or ``None`` for + a DataFrame fit. + predictors: The conditioning columns. + targets: The one categorical target, as a one-element list. + classes_: The target's categories, sorted; probability columns follow + this order. + weight_kind: The weight kind the fit resolved to, for the weights + audit (:func:`~microcosm.fit.model.resolved_weight_kind`). + """ + + def __init__( + self, + *, + entity: str | None, + predictors: list[str], + targets: list[str], + classes: np.ndarray, + features: _Features, + boosted_weight: float, + weight_kind: str, + seed: int, + ) -> None: + self.entity = entity + self.predictors = list(predictors) + self.targets = list(targets) + self.classes_ = classes + self.weight_kind = weight_kind + self.boosted_model: HistGradientBoostingClassifier | None = None + self.logit_model: _SplineLogit | None = None + self._features = features + self._boosted_weight = boosted_weight + self._draw_rng = np.random.default_rng(np.random.SeedSequence(seed).spawn(2)[1]) + + def _table(self, frame_or_df: Frame | pd.DataFrame) -> pd.DataFrame: + if isinstance(frame_or_df, Frame): + if self.entity is None: + raise ValueError("A DataFrame fit predicts on DataFrames only.") + return frame_or_df.table(self.entity) + missing = [c for c in self.predictors if c not in frame_or_df.columns] + if missing: + raise ValueError(f"Rows to predict for lack predictors {missing}.") + return frame_or_df + + def _full(self, model_classes: np.ndarray, proba: np.ndarray) -> np.ndarray: + out = np.zeros((len(proba), len(self.classes_))) + out[:, np.searchsorted(self.classes_, model_classes)] = proba + return out + + def component_proba( + self, frame_or_df: Frame | pd.DataFrame + ) -> dict[str, np.ndarray]: + """Each fitted learner's class probabilities, by learner name.""" + table = self._table(frame_or_df) + out: dict[str, np.ndarray] = {} + if self.boosted_model is not None: + out["boosted"] = self._full( + self.boosted_model.classes_, + self.boosted_model.predict_proba(self._features.boosted_matrix(table)), + ) + if self.logit_model is not None: + out["spline_logit"] = self._full( + self.logit_model.model.classes_, + self.logit_model.predict_proba(self._features, table), + ) + return out + + def predict_proba(self, frame_or_df: Frame | pd.DataFrame) -> np.ndarray: + """Class probabilities, one column per ``classes_`` entry.""" + table = self._table(frame_or_df) + if len(self.classes_) == 1: + self._features.boosted_matrix(table) # the same input checks + return np.ones((len(table), 1)) + components = self.component_proba(table) + if "spline_logit" not in components: + return components["boosted"] + if "boosted" not in components: + return components["spline_logit"] + weight = self._boosted_weight + return ( + weight * components["boosted"] + (1.0 - weight) * components["spline_logit"] + ) + + def predict_from_uniforms( + self, frame_or_df: Frame | pd.DataFrame, uniforms: np.ndarray + ) -> pd.DataFrame: + """Draw each row's category at its own uniform, by inverse CDF.""" + table = self._table(frame_or_df) + drawn = self.classes_[inverse_cdf_draw(self.predict_proba(table), uniforms)] + return pd.DataFrame({self.targets[0]: drawn}, index=table.index) + + def predict(self, frame_or_df: Frame | pd.DataFrame) -> pd.DataFrame: + """One stochastic draw per row from the model's seeded draw stream.""" + table = self._table(frame_or_df) + return self.predict_from_uniforms(table, self._draw_rng.random(len(table))) + + @property + def diagnostics(self) -> dict[str, int | None]: + """The learners' iteration counts (``None`` for a learner not fitted).""" + return { + "boosted_iterations": ( + None if self.boosted_model is None else int(self.boosted_model.n_iter_) + ), + "logit_iterations": ( + None if self.logit_model is None else self.logit_model.iterations + ), + } diff --git a/packages/microcosm-fit/src/microcosm/fit/donors.py b/packages/microcosm-fit/src/microcosm/fit/donors.py new file mode 100644 index 0000000000..7b94a73a32 --- /dev/null +++ b/packages/microcosm-fit/src/microcosm/fit/donors.py @@ -0,0 +1,170 @@ +"""Keyed nearest-donor choice within cells. + +Some values are copied whole from a donor rather than modelled one by one, so +that combinations that occur together stay together: an industry division and +its sector, say. Each recipient takes one donor from its cell (the donors that +share its categorical keys), among the ``k`` nearest on a distance the caller +builds, chosen with probability proportional to the donor's weight at the +recipient's own uniform. A build passes uniforms keyed on stable identities, so +a recipient's donor does not depend on which other recipients are drawn with it. +A cell with too few donors falls back to the next, coarser cell. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence + +import numpy as np +import pandas as pd +from sklearn.neighbors import NearestNeighbors + +__all__ = ["donor_distance_features", "keyed_nearest_donors"] + + +def _reference_ranks(values: np.ndarray, reference: np.ndarray) -> np.ndarray: + ordered = np.sort(reference) + if len(ordered) == 0: + return np.zeros(len(values)) + return np.searchsorted(ordered, values, side="right") / len(ordered) + + +def donor_distance_features( + recipients: pd.DataFrame, + donors: pd.DataFrame, + *, + rank_columns: Sequence[str] = (), + presence_rank_columns: Sequence[str] = (), + scaled_categoricals: Mapping[str, float] | None = None, +) -> tuple[np.ndarray, np.ndarray]: + """Recipient and donor coordinates for :func:`keyed_nearest_donors`. + + - ``rank_columns``: each value's rank among the donors' values, in [0, 1]. + - ``presence_rank_columns``: for amounts that are often zero, whether the + value is positive, and its rank among the donors' positive values + (0 when it is not positive). + - ``scaled_categoricals``: column -> scale; a one-hot on the donors' + levels times the scale, so a level mismatch costs that much distance. + + Returns: + ``(recipient_features, donor_features)``. + """ + scaled = dict(scaled_categoricals or {}) + columns = [*rank_columns, *presence_rank_columns, *scaled] + missing = [c for c in columns if c not in recipients or c not in donors] + if missing: + raise ValueError( + f"Distance columns missing from recipients or donors: {missing}." + ) + + def coordinates(frame: pd.DataFrame) -> np.ndarray: + parts = [] + for column in rank_columns: + parts.append( + _reference_ranks( + frame[column].to_numpy(np.float64), + donors[column].to_numpy(np.float64), + ) + ) + for column in presence_rank_columns: + values = frame[column].to_numpy(np.float64) + reference = donors[column].to_numpy(np.float64) + positive = values > 0 + parts.append(positive.astype(np.float64)) + parts.append( + np.where( + positive, _reference_ranks(values, reference[reference > 0]), 0.0 + ) + ) + for column, scale in scaled.items(): + levels = np.unique(donors[column].to_numpy()) + one_hot = frame[column].to_numpy()[:, None] == levels[None, :] + parts.extend(scale * one_hot.astype(np.float64).T) + if not parts: + raise ValueError("donor_distance_features needs at least one column.") + return np.column_stack(parts) + + return coordinates(recipients), coordinates(donors) + + +def keyed_nearest_donors( + recipient_features: np.ndarray, + donor_features: np.ndarray, + *, + recipient_cells: Sequence[Sequence[object] | np.ndarray], + donor_cells: Sequence[Sequence[object] | np.ndarray], + donor_weights: np.ndarray, + uniforms: np.ndarray, + k: int, +) -> tuple[np.ndarray, np.ndarray]: + """One donor per recipient: weighted, keyed, among its cell's ``k`` nearest. + + ``recipient_cells`` and ``donor_cells`` list the cell keys level by level, + finest first (for example (major group, status group), then major group + alone, then one cell for everyone). Keys are scalars: join several + categorical keys into one string. A recipient uses the finest level whose + cell holds at least ``k`` donors with positive weight; at the coarsest + level any positive-weight donor will do. Within the cell it takes the + ``k`` nearest donors (all, if fewer) and chooses one with probability + proportional to weight, at its uniform. + + Returns: + ``(donor_positions, levels)``: each recipient's donor, as a row + position in the donor arrays, and the cell level it was drawn from. + + Raises: + ValueError: If the inputs disagree in length, a uniform is outside + ``[0, 1)``, ``k`` is below 1, or a recipient has no donor with + positive weight at any level. + """ + recipient_features = np.asarray(recipient_features, dtype=np.float64) + donor_features = np.asarray(donor_features, dtype=np.float64) + weights = np.asarray(donor_weights, dtype=np.float64) + u = np.asarray(uniforms, dtype=np.float64) + n, m = len(recipient_features), len(donor_features) + if k < 1: + raise ValueError("k must be at least 1.") + if len(recipient_cells) != len(donor_cells) or not recipient_cells: + raise ValueError("Recipient and donor cells need the same, non-empty levels.") + if u.shape != (n,) or weights.shape != (m,): + raise ValueError("uniforms and donor_weights need one value per row.") + if not np.isfinite(u).all() or ((u < 0) | (u >= 1)).any(): + raise ValueError("Donor uniforms must be in [0, 1).") + if not np.isfinite(weights).all() or (weights < 0).any(): + raise ValueError("Donor weights must be finite and non-negative.") + positions = np.full(n, -1, dtype=np.int64) + levels = np.full(n, -1, dtype=np.int64) + usable = weights > 0 + last = len(recipient_cells) - 1 + for level, (r_keys, d_keys) in enumerate( + zip(recipient_cells, donor_cells, strict=True) + ): + r_keys = np.asarray(r_keys, dtype=object) + d_keys = np.asarray(d_keys, dtype=object) + if r_keys.shape != (n,) or d_keys.shape != (m,): + raise ValueError(f"Cell level {level} needs one key per row.") + waiting = np.flatnonzero(positions < 0) + if not len(waiting): + break + need = 1 if level == last else k + # Positions into ``waiting``, grouped by each waiting recipient's key. + for key, rows in pd.Series(waiting).groupby(r_keys[waiting]).indices.items(): + recipients = waiting[rows] + pool = np.flatnonzero(usable & (d_keys == key)) + if len(pool) < need: + continue + count = min(k, len(pool)) + _, nearest = ( + NearestNeighbors(n_neighbors=count) + .fit(donor_features[pool]) + .kneighbors(recipient_features[recipients]) + ) + cumulative = np.cumsum(weights[pool][nearest], axis=1) + cumulative /= cumulative[:, -1:] + pick = (cumulative > u[recipients, None]).argmax(axis=1) + positions[recipients] = pool[nearest[np.arange(len(recipients)), pick]] + levels[recipients] = level + if (positions < 0).any(): + raise ValueError( + "Some recipients have no donor with positive weight at any level." + ) + return positions, levels diff --git a/packages/microcosm-fit/src/microcosm/fit/held_out.py b/packages/microcosm-fit/src/microcosm/fit/held_out.py new file mode 100644 index 0000000000..28dbd974ac --- /dev/null +++ b/packages/microcosm-fit/src/microcosm/fit/held_out.py @@ -0,0 +1,198 @@ +"""Held-out evidence for a categorical model. + +A stage that draws categories can report how its model predicts rows it did not +train on: +- the out-of-fold log loss, beside a constant's (the training folds' weighted + class shares); +- the calibration slope, the one-parameter Platt map of the out-of-fold log + probabilities: 1 when the probabilities spread as much as the outcomes do, + above 1 when they are too flat, below 1 when they are too sharp; +- how far the predicted class shares sit from the observed ones, overall and + within the strata the caller names. + +Folds deal whole groups (a household's members, say) when ``groups`` is given, +so a group never sits on both sides of a fold. The folds and the slope reuse the +sign-gate calibration's machinery in :mod:`microcosm.fit.qrf`. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence + +import numpy as np +import pandas as pd + +from microcosm.fit import qrf as _qrf +from microcosm.fit.categorical import CategoricalClassifier + +__all__ = [ + "can_deal_folds", + "categorical_scores", + "out_of_fold_proba", + "stratified_folds", +] + +#: The probability a log loss floors a true class at, so one confident miss +#: cannot make the loss infinite. +LOG_LOSS_FLOOR = 1e-4 + + +def _group_codes( + groups: Sequence[object] | np.ndarray | None, n: int +) -> np.ndarray | None: + if groups is None: + return None + values = pd.Series(np.asarray(groups)) + if len(values) != n: + raise ValueError(f"groups has {len(values)} values for {n} rows.") + if values.isna().any(): + raise ValueError("groups must name a group for every row.") + return pd.factorize(values, sort=True)[0].astype(np.int64) + + +def can_deal_folds( + labels: Sequence[object] | np.ndarray, + folds: int, + groups: Sequence[object] | np.ndarray | None = None, +) -> bool: + """Whether every class has at least ``folds`` rows (or groups) to deal.""" + labels = np.asarray(labels) + codes = _group_codes(groups, len(labels)) + frame = pd.DataFrame({"label": labels}) + if codes is None: + counts = frame.groupby("label").size() + else: + counts = frame.assign(group=codes).drop_duplicates().groupby("label").size() + return bool(len(counts)) and int(counts.min()) >= folds + + +def stratified_folds( + labels: Sequence[object] | np.ndarray, + folds: int, + rng: np.random.Generator, + groups: Sequence[object] | np.ndarray | None = None, +) -> np.ndarray: + """A fold per row, each class's rows (or groups) dealt round the folds. + + With ``groups`` whole groups are dealt, each with the rarest class it + contains, so rows that share a group are never split across folds. + """ + labels = np.asarray(labels) + return _qrf._stratified_folds( + labels, folds, rng, groups=_group_codes(groups, len(labels)) + ) + + +def out_of_fold_proba( + model: CategoricalClassifier, + table: pd.DataFrame, + predictors: list[str], + target: str, + *, + weights: np.ndarray, + folds: np.ndarray, +) -> dict[str, np.ndarray]: + """Out-of-fold class probabilities for every row of ``table``. + + Each fold's rows are scored by the model fitted on the other folds. The + result maps ``"model"`` to the model's probabilities, each fitted learner's + name (``"boosted"``, ``"spline_logit"``) to its own, and ``"marginal"`` to + the training folds' weighted class shares; ``"classes"`` holds the column + order, the sorted categories of ``table[target]``. + """ + weights = np.asarray(weights, dtype=np.float64) + folds = np.asarray(folds) + if weights.shape != (len(table),) or folds.shape != (len(table),): + raise ValueError("weights and folds need one value per row.") + labels = table[target].to_numpy() + classes = np.unique(labels) + out: dict[str, np.ndarray] = {"classes": classes} + + def full(fitted_classes: np.ndarray, proba: np.ndarray) -> np.ndarray: + result = np.zeros((len(proba), len(classes))) + result[:, np.searchsorted(classes, fitted_classes)] = proba + return result + + for fold in np.unique(folds): + train, test = folds != fold, folds == fold + fitted = model.fit( + table.loc[train], predictors, [target], weights=weights[train] + ) + scored = {"model": fitted.predict_proba(table.loc[test])} + scored.update(fitted.component_proba(table.loc[test])) + shares = pd.Series(weights[train]).groupby(labels[train]).sum() + shares = shares.reindex(classes, fill_value=0.0).to_numpy() + for name, proba in scored.items(): + out.setdefault(name, np.zeros((len(table), len(classes)))) + out[name][test] = full(fitted.classes_, proba) + out.setdefault("marginal", np.zeros((len(table), len(classes)))) + out["marginal"][test] = shares / shares.sum() + return out + + +def _share_gap(proba: np.ndarray, observed: np.ndarray, w: np.ndarray) -> float: + total = w.sum() + return float(0.5 * np.abs((w @ proba - w @ observed) / total).sum()) + + +def categorical_scores( + proba: np.ndarray, + labels: Sequence[object] | np.ndarray, + classes: np.ndarray, + weights: np.ndarray, + *, + strata: Mapping[str, Sequence[object] | np.ndarray] | None = None, +) -> dict[str, object]: + """Log loss, calibration slope and class-share gaps of probabilities. + + Args: + proba: Class probabilities (out of fold), one column per ``classes``. + labels: Each row's observed category. + classes: The categories in column order. + weights: Per-row weights. + strata: Name -> one stratum label per row. Share gaps (total + variation between the weighted predicted and observed class + shares) are reported within each level. + + Returns: + ``log_loss`` (true-class probabilities floored at + :data:`LOG_LOSS_FLOOR`), ``share_gap`` overall, ``calibration_slope`` + (``None`` where the Platt fit fell back to class rates) with its + ``calibration_outcome``, and ``strata``: name -> level -> + ``{"rows", "weight", "share_gap"}``. Counts are raw: a caller that + publishes them bands them first. + """ + proba = np.asarray(proba, dtype=np.float64) + labels = np.asarray(labels) + w = np.asarray(weights, dtype=np.float64) + index = np.searchsorted(classes, labels) + if (index >= len(classes)).any() or ( + classes[np.minimum(index, len(classes) - 1)] != labels + ).any(): + raise ValueError("Every label must be one of classes.") + rows = np.arange(len(labels)) + observed = np.zeros_like(proba) + observed[rows, index] = 1.0 + true_class = np.maximum(proba[rows, index], LOG_LOSS_FLOOR) + slope, _, outcome = _qrf._fit_gate_calibration(_qrf._log_proba(proba), index, w) + result: dict[str, object] = { + "log_loss": float(w @ -np.log(true_class) / w.sum()), + "share_gap": _share_gap(proba, observed, w), + "calibration_slope": ( + float(slope) if outcome == _qrf.GateOutcome.CROSS_FITTED else None + ), + "calibration_outcome": str(outcome), + "strata": {}, + } + for name, stratum in (strata or {}).items(): + stratum = np.asarray(stratum) + levels: dict[object, dict[str, float | int]] = {} + for level in np.unique(stratum): + mask = stratum == level + levels[level.item() if hasattr(level, "item") else level] = { + "rows": int(mask.sum()), + "weight": float(w[mask].sum()), + "share_gap": _share_gap(proba[mask], observed[mask], w[mask]), + } + result["strata"][name] = levels + return result diff --git a/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py b/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py new file mode 100644 index 0000000000..a673dbb80f --- /dev/null +++ b/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py @@ -0,0 +1,222 @@ +"""The categorical classifier: weights, learners, the blend and keyed draws. + +A code (an occupation group, an industry) cannot go through the quantile forest, +which interpolates. These tests pin the categorical model's contract: the +package's weight rules, the two learners and their mixture, reproducible fits, +draws that follow each row's own uniform, and loud refusals. +""" + +from __future__ import annotations + +import numpy as np +import pandas as pd +import pytest + +from microcosm.fit import ( + BoostedClassifierSettings, + CategoricalClassifier, + SplineLogitSettings, + inverse_cdf_draw, +) +from microcosm.fit.model import FittedModel + + +def _planted(n: int = 1200, seed: int = 0) -> pd.DataFrame: + """Pay picks the class: low pay mostly 'a', middling 'b', high 'c'.""" + rng = np.random.default_rng(seed) + pay = rng.lognormal(10.0, 1.0, n) + group = rng.choice(["north", "south"], n) + cut = np.quantile(pay, [1 / 3, 2 / 3]) + base = np.digitize(pay, cut) + noisy = np.where(rng.random(n) < 0.15, rng.integers(0, 3, n), base) + return pd.DataFrame( + { + "pay": pay, + "age": rng.integers(18, 80, n).astype(float), + "group": group, + "label": np.array(["a", "b", "c"])[noisy], + "weight": rng.uniform(0.5, 2.0, n), + } + ) + + +def _model(**overrides) -> CategoricalClassifier: + settings = { + "categorical_predictors": ("group",), + "arcsinh_scales": {"pay": 1000.0}, + "boosted": BoostedClassifierSettings(max_iter=60), + "seed": 3, + } + settings.update(overrides) + return CategoricalClassifier(**settings) + + +PREDICTORS = ["pay", "age", "group"] + + +def test_dataframe_fit_requires_explicit_weights() -> None: + with pytest.raises(ValueError, match="no typed weights"): + _model().fit(_planted(), PREDICTORS, ["label"]) + + +def test_unweighted_fit_must_be_asked_for() -> None: + fitted = _model().fit(_planted(), PREDICTORS, ["label"], weights="none") + assert fitted.weight_kind == "none" + + +def test_fitted_model_is_a_fitted_model_and_recovers_the_planted_signal() -> None: + data = _planted() + fitted = _model().fit(data, PREDICTORS, ["label"], weights="weight") + assert isinstance(fitted, FittedModel) + assert list(fitted.classes_) == ["a", "b", "c"] + proba = fitted.predict_proba(data) + assert np.allclose(proba.sum(axis=1), 1.0) + low, high = ( + data["pay"] < data["pay"].quantile(0.2), + data["pay"] > data["pay"].quantile(0.8), + ) + assert proba[low.to_numpy(), 0].mean() > 0.7 + assert proba[high.to_numpy(), 2].mean() > 0.7 + + +@pytest.mark.parametrize("weight, learner", [(1.0, "boosted"), (0.0, "spline_logit")]) +def test_a_weight_of_one_or_zero_is_one_learner(weight, learner) -> None: + data = _planted() + fitted = _model(boosted_weight=weight).fit( + data, PREDICTORS, ["label"], weights="weight" + ) + components = fitted.component_proba(data) + assert list(components) == [learner] + assert np.allclose(fitted.predict_proba(data), components[learner]) + + +def test_the_blend_is_the_weighted_average_of_its_learners() -> None: + data = _planted() + fitted = _model(boosted_weight=0.25).fit( + data, PREDICTORS, ["label"], weights="weight" + ) + components = fitted.component_proba(data) + expected = 0.25 * components["boosted"] + 0.75 * components["spline_logit"] + assert np.allclose(fitted.predict_proba(data), expected) + assert fitted.diagnostics["boosted_iterations"] >= 1 + assert fitted.diagnostics["logit_iterations"] >= 1 + + +def test_the_same_seed_refits_identically() -> None: + data = _planted() + first = _model().fit(data, PREDICTORS, ["label"], weights="weight") + second = _model().fit(data, PREDICTORS, ["label"], weights="weight") + assert np.array_equal(first.predict_proba(data), second.predict_proba(data)) + + +def test_draws_follow_each_rows_own_uniform() -> None: + data = _planted() + fitted = _model().fit(data, PREDICTORS, ["label"], weights="weight") + u = np.random.default_rng(9).random(len(data)) + drawn = fitted.predict_from_uniforms(data, u)["label"].to_numpy() + expected = fitted.classes_[inverse_cdf_draw(fitted.predict_proba(data), u)] + assert np.array_equal(drawn, expected) + # A row's draw depends on its own uniform only: reorder the rows. + order = np.random.default_rng(10).permutation(len(data)) + reordered = fitted.predict_from_uniforms(data.iloc[order], u[order])["label"] + assert np.array_equal(reordered.to_numpy(), drawn[order]) + + +def test_draws_reproduce_the_probabilities_in_aggregate() -> None: + data = _planted(4000) + fitted = _model().fit(data, PREDICTORS, ["label"], weights="weight") + u = np.random.default_rng(11).random(len(data)) + drawn = fitted.predict_from_uniforms(data, u)["label"].to_numpy() + shares = np.array([(drawn == c).mean() for c in fitted.classes_]) + assert np.allclose(shares, fitted.predict_proba(data).mean(axis=0), atol=0.03) + + +def test_predict_is_a_seeded_draw_stream() -> None: + data = _planted() + first = _model().fit(data, PREDICTORS, ["label"], weights="weight") + second = _model().fit(data, PREDICTORS, ["label"], weights="weight") + assert first.predict(data).equals(second.predict(data)) + + +def test_inverse_cdf_draw_places_uniforms_by_cumulative_probability() -> None: + proba = np.array([[0.2, 0.5, 0.3]] * 4) + assert inverse_cdf_draw(proba, np.array([0.0, 0.19, 0.2, 0.999999])).tolist() == [ + 0, + 0, + 1, + 2, + ] + + +@pytest.mark.parametrize( + "proba, uniforms", + [ + (np.array([[0.5, 0.6]]), np.array([0.1])), + (np.array([[1.2, -0.2]]), np.array([0.1])), + (np.array([[0.5, 0.5]]), np.array([1.0])), + (np.array([[0.5, 0.5]]), np.array([0.1, 0.2])), + ], +) +def test_inverse_cdf_draw_refuses_bad_input(proba, uniforms) -> None: + with pytest.raises(ValueError): + inverse_cdf_draw(proba, uniforms) + + +def test_a_logit_that_does_not_converge_is_refused() -> None: + model = _model(boosted_weight=0.0, logit=SplineLogitSettings(max_iter=1)) + with pytest.raises(ValueError, match="did not converge"): + model.fit(_planted(), PREDICTORS, ["label"], weights="weight") + + +def test_unseen_categories_at_prediction_are_refused() -> None: + data = _planted() + fitted = _model().fit(data, PREDICTORS, ["label"], weights="weight") + with pytest.raises(ValueError, match="never saw"): + fitted.predict_proba(data.assign(group="east")) + + +def test_non_finite_numeric_predictors_are_refused() -> None: + data = _planted() + data.loc[3, "pay"] = np.nan + with pytest.raises(ValueError, match="non-finite"): + _model().fit(data, PREDICTORS, ["label"], weights="weight") + + +def test_a_missing_label_is_refused() -> None: + data = _planted() + data.loc[5, "label"] = None + with pytest.raises(ValueError, match="no category"): + _model().fit(data, PREDICTORS, ["label"], weights="weight") + + +@pytest.mark.parametrize( + "overrides, message", + [ + ({"boosted_weight": 1.5}, "boosted_weight"), + ({"arcsinh_scales": {"pay": 0.0}}, "positive"), + ], +) +def test_bad_settings_are_refused(overrides, message) -> None: + with pytest.raises(ValueError, match=message): + _model(**overrides) + + +def test_settings_must_name_predictors() -> None: + with pytest.raises(ValueError, match="not predictors"): + _model(categorical_predictors=("region",)).fit( + _planted(), PREDICTORS, ["label"], weights="weight" + ) + + +def test_exactly_one_target() -> None: + data = _planted().assign(other="x") + with pytest.raises(ValueError, match="exactly one target"): + _model().fit(data, PREDICTORS, ["label", "other"], weights="weight") + + +def test_a_single_class_draws_that_class() -> None: + data = _planted().assign(label="only") + fitted = _model().fit(data, PREDICTORS, ["label"], weights="weight") + assert fitted.predict_proba(data).shape == (len(data), 1) + drawn = fitted.predict_from_uniforms(data, np.full(len(data), 0.5)) + assert set(drawn["label"]) == {"only"} diff --git a/packages/microcosm-fit/tests/engine_free/shared/test_donors.py b/packages/microcosm-fit/tests/engine_free/shared/test_donors.py new file mode 100644 index 0000000000..340794e901 --- /dev/null +++ b/packages/microcosm-fit/tests/engine_free/shared/test_donors.py @@ -0,0 +1,153 @@ +"""Keyed nearest-donor choice: cells, fallbacks, weights and the caller's uniforms.""" + +from __future__ import annotations + +import numpy as np +import pandas as pd +import pytest + +from microcosm.fit import donor_distance_features, keyed_nearest_donors + + +def _donors(n: int = 400, seed: int = 0) -> pd.DataFrame: + rng = np.random.default_rng(seed) + return pd.DataFrame( + { + "cell": rng.choice(["a", "b"], n), + "age": rng.integers(18, 80, n).astype(float), + "pay": np.where(rng.random(n) < 0.3, 0.0, rng.lognormal(10, 1, n)), + "area": rng.choice(["x", "y", "z"], n), + "weight": rng.uniform(0.5, 2.0, n), + } + ) + + +def _features(recipients: pd.DataFrame, donors: pd.DataFrame): + return donor_distance_features( + recipients, + donors, + rank_columns=["age"], + presence_rank_columns=["pay"], + scaled_categoricals={"area": 0.3}, + ) + + +def test_features_rank_against_the_donors() -> None: + donors = pd.DataFrame( + { + "age": [20.0, 40.0, 60.0, 80.0], + "pay": [0.0, 1.0, 2.0, 3.0], + "area": list("xxyy"), + } + ) + recipients = pd.DataFrame({"age": [40.0], "pay": [0.0], "area": ["y"]}) + r, d = _features(recipients, donors) + # age rank 2/4; pay absent; area one-hot (x, y) times 0.3. + assert r.tolist() == [[0.5, 0.0, 0.0, 0.0, 0.3]] + assert d.shape == (4, 5) + + +def test_each_recipient_draws_from_its_own_cell() -> None: + donors = _donors() + recipients = _donors(100, seed=1) + r, d = _features(recipients, donors) + positions, levels = keyed_nearest_donors( + r, + d, + recipient_cells=[recipients["cell"].to_numpy(), np.zeros(len(recipients))], + donor_cells=[donors["cell"].to_numpy(), np.zeros(len(donors))], + donor_weights=donors["weight"].to_numpy(), + uniforms=np.random.default_rng(2).random(len(recipients)), + k=20, + ) + assert (levels == 0).all() + assert (donors["cell"].to_numpy()[positions] == recipients["cell"].to_numpy()).all() + + +def test_a_thin_cell_falls_back_to_the_coarser_level() -> None: + donors = _donors() + donors.loc[donors.index[:3], "cell"] = "thin" + recipients = _donors(10, seed=3).assign(cell="thin") + r, d = _features(recipients, donors) + positions, levels = keyed_nearest_donors( + r, + d, + recipient_cells=[recipients["cell"].to_numpy(), np.zeros(10)], + donor_cells=[donors["cell"].to_numpy(), np.zeros(len(donors))], + donor_weights=donors["weight"].to_numpy(), + uniforms=np.full(10, 0.5), + k=20, + ) + assert (levels == 1).all() + assert (positions >= 0).all() + + +def test_a_recipients_donor_depends_on_its_own_uniform_only() -> None: + donors = _donors() + recipients = _donors(60, seed=4) + u = np.random.default_rng(5).random(60) + r, d = _features(recipients, donors) + cells = ([recipients["cell"].to_numpy()], [donors["cell"].to_numpy()]) + positions, _ = keyed_nearest_donors( + r, + d, + recipient_cells=cells[0], + donor_cells=cells[1], + donor_weights=donors["weight"].to_numpy(), + uniforms=u, + k=10, + ) + order = np.random.default_rng(6).permutation(60) + shuffled, _ = keyed_nearest_donors( + r[order], + d, + recipient_cells=[cells[0][0][order]], + donor_cells=cells[1], + donor_weights=donors["weight"].to_numpy(), + uniforms=u[order], + k=10, + ) + assert np.array_equal(shuffled, positions[order]) + + +def test_choice_follows_the_donor_weights() -> None: + donors = pd.DataFrame({"age": [30.0, 30.0], "weight": [1.0, 3.0]}) + recipients = pd.DataFrame({"age": np.full(4000, 30.0)}) + r, d = donor_distance_features(recipients, donors, rank_columns=["age"]) + positions, _ = keyed_nearest_donors( + r, + d, + recipient_cells=[np.zeros(4000)], + donor_cells=[np.zeros(2)], + donor_weights=donors["weight"].to_numpy(), + uniforms=np.random.default_rng(7).random(4000), + k=2, + ) + assert (positions == 1).mean() == pytest.approx(0.75, abs=0.03) + + +def test_no_donor_at_any_level_is_refused() -> None: + r = np.zeros((1, 1)) + with pytest.raises(ValueError, match="no donor"): + keyed_nearest_donors( + r, + np.zeros((2, 1)), + recipient_cells=[np.array(["a"])], + donor_cells=[np.array(["b", "b"])], + donor_weights=np.ones(2), + uniforms=np.array([0.5]), + k=1, + ) + + +def test_bad_uniforms_are_refused() -> None: + with pytest.raises(ValueError, match=r"\[0, 1\)"): + keyed_nearest_donors( + np.zeros((1, 1)), + np.zeros((1, 1)), + recipient_cells=[np.zeros(1)], + donor_cells=[np.zeros(1)], + donor_weights=np.ones(1), + uniforms=np.array([1.0]), + k=1, + ) diff --git a/packages/microcosm-fit/tests/engine_free/shared/test_held_out.py b/packages/microcosm-fit/tests/engine_free/shared/test_held_out.py new file mode 100644 index 0000000000..c365a175bc --- /dev/null +++ b/packages/microcosm-fit/tests/engine_free/shared/test_held_out.py @@ -0,0 +1,120 @@ +"""Held-out evidence for categorical models: folds, out-of-fold probabilities, scores.""" + +from __future__ import annotations + +import numpy as np +import pandas as pd +import pytest + +from microcosm.fit import ( + BoostedClassifierSettings, + CategoricalClassifier, + can_deal_folds, + categorical_scores, + out_of_fold_proba, + stratified_folds, +) + + +def test_folds_deal_whole_groups_and_every_class() -> None: + rng = np.random.default_rng(0) + groups = np.repeat(np.arange(200), 3) + labels = np.where(groups % 4 == 0, "rare", "common") + folds = stratified_folds(labels, 5, rng, groups=groups) + by_group = pd.Series(folds).groupby(groups).nunique() + assert (by_group == 1).all() + for fold in range(5): + assert set(labels[folds == fold]) == {"rare", "common"} + + +def test_can_deal_folds_counts_groups_not_rows() -> None: + labels = np.array(["a"] * 10 + ["b"] * 10) + one_household_of_b = np.r_[np.arange(10), np.full(10, 99)] + assert can_deal_folds(labels, 5) + assert not can_deal_folds(labels, 5, groups=one_household_of_b) + + +def _data(n: int = 900) -> pd.DataFrame: + rng = np.random.default_rng(1) + x = rng.normal(0, 1, n) + label = np.where(x + rng.normal(0, 0.7, n) > 0, "up", "down") + return pd.DataFrame({"x": x, "label": label, "weight": rng.uniform(0.5, 2, n)}) + + +def test_out_of_fold_scores_every_row_once_with_each_learner() -> None: + data = _data() + model = CategoricalClassifier(boosted=BoostedClassifierSettings(max_iter=40)) + folds = stratified_folds(data["label"].to_numpy(), 5, np.random.default_rng(2)) + out = out_of_fold_proba( + model, data, ["x"], "label", weights=data["weight"].to_numpy(), folds=folds + ) + assert list(out["classes"]) == ["down", "up"] + for name in ("model", "boosted", "spline_logit", "marginal"): + assert out[name].shape == (len(data), 2) + assert np.allclose(out[name].sum(axis=1), 1.0) + assert np.allclose(out["model"], 0.5 * (out["boosted"] + out["spline_logit"])) + + +def test_scores_reward_the_model_over_the_constant() -> None: + data = _data() + model = CategoricalClassifier(boosted=BoostedClassifierSettings(max_iter=40)) + folds = stratified_folds(data["label"].to_numpy(), 5, np.random.default_rng(2)) + w = data["weight"].to_numpy() + out = out_of_fold_proba(model, data, ["x"], "label", weights=w, folds=folds) + labels = data["label"].to_numpy() + fitted = categorical_scores(out["model"], labels, out["classes"], w) + constant = categorical_scores(out["marginal"], labels, out["classes"], w) + assert fitted["log_loss"] < constant["log_loss"] - 0.2 + assert fitted["calibration_outcome"] == "cross_fitted" + assert 0.8 < fitted["calibration_slope"] < 1.2 + + +def _calibrated(n: int = 20000, seed: int = 4): + """Probabilities and outcomes drawn from them, so the slope is about 1.""" + rng = np.random.default_rng(seed) + logits = rng.normal(0, 1.5, (n, 3)) + proba = np.exp(logits) / np.exp(logits).sum(axis=1, keepdims=True) + labels = (np.cumsum(proba, axis=1) > rng.random(n)[:, None]).argmax(axis=1) + return proba, labels, np.ones(n) + + +def _tempered(proba: np.ndarray, power: float) -> np.ndarray: + scaled = proba**power + return scaled / scaled.sum(axis=1, keepdims=True) + + +def test_slope_reads_the_spread_of_the_probabilities() -> None: + proba, labels, w = _calibrated() + classes = np.arange(3) + right = categorical_scores(proba, labels, classes, w)["calibration_slope"] + flat = categorical_scores(_tempered(proba, 0.5), labels, classes, w)[ + "calibration_slope" + ] + sharp = categorical_scores(_tempered(proba, 2.0), labels, classes, w)[ + "calibration_slope" + ] + assert abs(right - 1.0) < 0.05 + assert flat > 1.5 + assert sharp < 0.7 + + +def test_share_gaps_within_strata() -> None: + labels = np.array([0, 0, 1, 1]) + proba = np.array([[1.0, 0.0], [1.0, 0.0], [1.0, 0.0], [0.0, 1.0]]) + scores = categorical_scores( + proba, + labels, + np.array([0, 1]), + np.ones(4), + strata={"half": ["x", "x", "y", "y"]}, + ) + assert scores["share_gap"] == pytest.approx(0.25) + assert scores["strata"]["half"]["x"] == {"rows": 2, "weight": 2.0, "share_gap": 0.0} + assert scores["strata"]["half"]["y"]["share_gap"] == pytest.approx(0.5) + + +def test_labels_outside_the_classes_are_refused() -> None: + with pytest.raises(ValueError, match="one of classes"): + categorical_scores( + np.array([[1.0]]), np.array(["b"]), np.array(["a"]), np.ones(1) + ) From 5af0401b9746371c4ee84e30205c6c8d344bcada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:00:54 +0000 Subject: [PATCH 2/7] Carry the FRS occupation into the UK spine as soc2020_major_group (#1490) frs_employment now reads adult.tab's SOC2020, which codes the SOC 2020 major group as 1000-9000 (0 undefined), and writes policyengine-uk's soc2020_major_group: the SOC2020MajorGroup member names, held once in uk_runtime/occupation_constants.py with the FRS view derived beside them. The FRS asks the employment questions of everyone who has ever worked, so the group is the main job's, or the last job's for an adult not in work (2024-25 question instructions, details of employment, p. 183; PDF p. 184). Child-table people are NONE. An adult with a blank or unknown code refuses the build, naming the codes and never a count, as EMPSTATI does; soc2020 is direct-indexed like sic. The column joins the export allow-list, and a terminal gate, uk_soc2020_major_group_enum_domain, keeps it inside the engine's enum, which policyengine-uk has from 2.173.0. The gate moves the battery's three vintage digests and the release-cut part's two (spine and calibration seam are unchanged); the coverage manifest's source digests and the H2 fixture (a SOC2020 column in the synthetic adult.tab, 30 normalised string columns) are regenerated. Checked on the real FRS 2024-25 adult.tab (digest-verified): every adult maps to its own code's group and every child-table person is NONE. Co-Authored-By: Claude Opus 5.5 --- changelog.d/1490-uk-occupation-carry.added.md | 3 + .../src/microcosm/build/uk/gates.json | 13 + .../uk/release_input_coverage_manifest.json | 50 ++-- .../src/microcosm/build/uk/source_stages.json | 7 +- .../src/microcosm/build/uk/spec/sources.yaml | 5 +- .../build/uk_runtime/calibration_run.py | 1 + .../build/uk_runtime/frs_employment.py | 55 +++- .../src/microcosm/build/uk_runtime/graph.py | 1 + .../build/uk_runtime/occupation_constants.py | 43 +++ .../build/uk_runtime/terminal_gates.py | 1 + .../engine/uk/test_uk_occupation_constants.py | 23 ++ .../engine_free/shared/test_country_spec.py | 1 + .../uk/test_uk_battery_bindings.py | 6 +- .../engine_free/uk/test_uk_frs_employment.py | 113 +++++++- .../uk/test_uk_frs_legacy_proxies.py | 8 +- .../tests/engine_free/uk/test_uk_frs_spine.py | 1 + .../uk/test_uk_occupation_constants.py | 40 +++ .../src/microcosm/data/contract.py | 13 +- .../tests/engine_free/shared/test_contract.py | 11 +- .../adapters/policyengine_uk_concepts.py | 9 - .../fixtures/parity/uk_spine/NORMALIZATION.md | 4 +- .../parity/uk_spine/sources/fixture.json | 35 +-- .../parity/uk_spine/sources/frs_raw/adult.tab | 272 +++++++++--------- tools/graph_uk_spine_fixture.py | 8 +- 24 files changed, 505 insertions(+), 218 deletions(-) create mode 100644 changelog.d/1490-uk-occupation-carry.added.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py create mode 100644 packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py create mode 100644 packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py diff --git a/changelog.d/1490-uk-occupation-carry.added.md b/changelog.d/1490-uk-occupation-carry.added.md new file mode 100644 index 0000000000..2b7fdc4468 --- /dev/null +++ b/changelog.d/1490-uk-occupation-carry.added.md @@ -0,0 +1,3 @@ +The UK spine now carries the FRS's own occupation as policyengine-uk's `soc2020_major_group` (microcosm#1490). `frs_employment` reads the adult table's `SOC2020` code, which gives the SOC 2020 major group as 1000-9000, and maps it to the engine's `SOC2020MajorGroup` names, held once in `occupation_constants`. The FRS asks the employment questions of everyone who has ever worked, so the group is the main job's, or the last job's for an adult not in work; child-table people are `NONE`, and an adult with a blank or unknown code refuses the build. + +The column is on the export allow-list, and a terminal gate, `uk_soc2020_major_group_enum_domain`, keeps it inside the engine's enum. The engine has the enum from policyengine-uk 2.173.0. diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index d4653b0d56..e5c94cf3b3 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -1426,6 +1426,7 @@ "person.salary_sacrifice_asked", "person.salary_sacrifice_reported", "person.sic_industry_division", + "person.soc2020_major_group", "person.stands_as_sole_owner_or_partner_of_company", "person.statutory_paternity_pay", "person.student_loan_balance", @@ -1629,6 +1630,18 @@ }, "notes": "The person student-loan plan assignment must remain inside the PolicyEngine-UK StudentLoanPlan enum domain." }, + { + "id": "uk_soc2020_major_group_enum_domain", + "gate": "enum_domain", + "phase": "terminal", + "criticality": "release_blocking", + "parameters": { + "columns": [ + "soc2020_major_group" + ] + }, + "notes": "The person SOC 2020 major group must remain inside the PolicyEngine-UK SOC2020MajorGroup enum domain. Checked on the frame the release ships, after every stage that writes the column: frs_employment carries the FRS code, and a later stage may redraw it (microcosm#1490)." + }, { "id": "uk_council_tax_band_domain_terminal", "gate": "enum_domain", 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 c38819d8dc..1e4275e332 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 @@ -472,7 +472,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -495,7 +495,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -518,7 +518,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -540,7 +540,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -570,7 +570,7 @@ "uc_is_in_gainful_self_employment" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "The FRS job record's company car answers through frs_spine's carriers (EXPBEN01, EXPBEN03, CARVAL, FUELTYP, CARCON, CARAMT), WAS round-8 company cars' list prices, and HMRC's 2024-25 company car recipients by CO2 band (Table 2A) and fuel (Table 2C), via the vendored facts", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" @@ -599,7 +599,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -619,7 +619,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -641,7 +641,7 @@ "required_mass_change_reason": "High-value home support divides every owner household in the top value stratum of its region into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "Microcosm structural operator (microcosm#1240 fix 1); no publisher input", "survey": "Family Resources Survey 2024-25 and SPI synthetic support, after the WAS wealth draw and the regional property uprating" @@ -662,7 +662,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -686,7 +686,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "6a2ba5e3e43c6d7936416552aadc716729b902dcac24b97093ae8ccf06cf8a8f", @@ -776,7 +776,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -803,7 +803,7 @@ "required_mass_change_reason": "ISA subscriptions per adult from HMRC's ISA tables on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "HMRC Individual Savings Account statistics Tables 9.4, 9.6 and 9.7 to 9.9, the cash ISA limit reduction impact note and Lifetime ISA Table 1a, via the vendored facts; Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "HMRC Annual savings statistics (September 2026 release); Wealth and Assets Survey round 8" @@ -873,7 +873,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "UK Data Service SN 9603 Living Costs and Food Survey 2024-25 (2nd edition) household/person tabs and the vendored Chronicle facts for NEED 2024 mean kWh, DESNZ Energy Trends and QEP average prices paid for calendar 2024, road-fuel outturn (DESNZ, HMRC, ONS Consumer Trends) and road fuel by vehicle type (DESNZ), ONS Consumer Trends household spending by COICOP division, the DfT VEH1103 licensed-car stock, NTS bus use, the NTS private cars (UK Data Service SN 5340, End User Licence; the vehicle and household tabs, survey years 2022-2024) for the zero-emission share by income fifth and the household-paid road-fuel mix, and the DfT and devolved bus finance tables and fares indices.", "survey": "Living Costs and Food Survey 2024-25" @@ -899,7 +899,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -919,7 +919,7 @@ "required_mass_change_reason": "Private-school attendance stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "policyengine-uk attends_private_school (the gov.simulation.private_school_vat attendance rates and factor), evaluated by the pinned engine", "survey": "policyengine-uk private-school attendance imputation, stored at the spine's weights" @@ -942,7 +942,7 @@ "property_finance_costs" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/property-rental-income-statistics", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Property Rental Income Statistics 2026 (tax year 2024-25)" @@ -963,7 +963,7 @@ "required_mass_change_reason": "Annual property purchases imputed on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/uk-stamp-tax-statistics", "survey": "HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected 11 March 2026), Tables 6b, 8a and 8b" @@ -986,7 +986,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "uk/high_value_home_value_knots.json, built by tools/build_uk_high_value_home_stock.py from PolicyEngine/chronicle#343's registrations", "survey": "HM Land Registry Price Paid latest sales uprated with the UK House Price Index, owner-weighted by region (the dense value node's knots, region level)" @@ -1010,7 +1010,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "MHCLG dwellings and the UK House Price Index regional average price averaged over the twelve months of calendar 2024 from the July 2026 full file, the frame's valuation basis, so the engine's annual uprating from 2024 projects the value once (microcosm#1240 fix 5).", "survey": "Public regional property reference" @@ -1038,7 +1038,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -1071,7 +1071,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -1094,7 +1094,7 @@ "student_loan_balance" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "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" @@ -1114,7 +1114,7 @@ "required_mass_change_reason": "Self-employed gross receipts stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "self_employment_income after the SPI income stage; HMRC's published gainers of the raise to GBP 3,000, about 400,000 taxpayers with a lower bill by about GBP 380 on average", "survey": "The self-employed's own profit on the final spine, and HMRC's policy paper on the Budget 2026 trading allowance raise (calibration)" @@ -1136,7 +1136,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -1175,7 +1175,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": "c97cf273cb71f64e39a90fa41330d3e66e09414d81a60c8dad91bdac3816d26f", + "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index 2fbaba0c2d..c68f2faeb5 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -738,18 +738,19 @@ }, { "kind": "map_coded_amounts", - "scope": "empstati employment status, mjobsect sector, and raw SIC division" + "scope": "empstati employment status, mjobsect sector, raw SIC division, and SOC2020 major group" } ], "outputs": [ "employment_status", "employment_sector", - "sic_industry_division" + "sic_industry_division", + "soc2020_major_group" ], "nonnegative_outputs": [ "sic_industry_division" ], - "notes": "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. mjobsect and sic are direct-indexed and fail loudly if absent." + "notes": "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. SOC2020 codes the SOC 2020 major group as 1000-9000 (0 undefined) and maps to policyengine-uk's SOC2020MajorGroup names (occupation_constants); it is the main job, or the last job for an adult not in work, since the FRS asks the employment questions of everyone who has ever worked (2024-25 question instructions, details of employment, p. 183; PDF p. 184). People outside adult.tab are NONE, and an adult with a blank or unknown SOC2020 code refuses the build (microcosm#1490). mjobsect, sic and soc2020 are direct-indexed and fail loudly if absent." }, { "stage": "frs_council_tax", 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 0541b13856..d31e90995c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -741,14 +741,15 @@ stages: numeric_errors: coerce runtime_sha256_required: true - kind: map_coded_amounts - scope: empstati employment status, mjobsect sector, and raw SIC division + scope: empstati employment status, mjobsect sector, raw SIC division, and SOC2020 major group outputs: - employment_status - employment_sector - sic_industry_division + - soc2020_major_group nonnegative_outputs: - sic_industry_division - notes: "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. mjobsect and sic are direct-indexed and fail loudly if absent." + notes: "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. SOC2020 codes the SOC 2020 major group as 1000-9000 (0 undefined) and maps to policyengine-uk's SOC2020MajorGroup names (occupation_constants); it is the main job, or the last job for an adult not in work, since the FRS asks the employment questions of everyone who has ever worked (2024-25 question instructions, details of employment, p. 183; PDF p. 184). People outside adult.tab are NONE, and an adult with a blank or unknown SOC2020 code refuses the build (microcosm#1490). mjobsect, sic and soc2020 are direct-indexed and fail loudly if absent." - stage: frs_council_tax survey: Family Resources Survey 2024-25 source: Department for Work and Pensions Family Resources Survey 2024-25, UK Data Service SN 9563, DOI 10.5255/UKDA-SN-9563-1; local licensed 2024_25 tabs. 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 1e4e00c95e..249f8c3c2a 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 @@ -194,6 +194,7 @@ "uk_export_surface", "uk_take_up_signal", "uk_student_loan_plan_enum_domain", + "uk_soc2020_major_group_enum_domain", # The spine checks council_tax_band at the transferred boundary; this # instance checks the release frame, after any later step that writes the # band (microcosm#1278). diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_employment.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_employment.py index 9dddd51534..bf2bc7488b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_employment.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/frs_employment.py @@ -21,6 +21,10 @@ uk_time_period, validate_uk_national_frame, ) +from microcosm.build.uk_runtime.occupation_constants import ( + UK_FRS_SOC2020_MAJOR_GROUP, + UK_SOC2020_NO_OCCUPATION, +) from microcosm.frame import Frame # Adult-table EMPSTATI ("Adult - Employment Status - ILO definition") value @@ -53,6 +57,7 @@ "employment_status", "employment_sector", "sic_industry_division", + "soc2020_major_group", ) @@ -74,7 +79,7 @@ def output_columns() -> tuple[str, ...]: def add_frs_employment( frame: Frame, raw_dir: str | Path, *, stage: SourceStageSpec ) -> Frame: - """Add employment status, sector, and SIC from pinned ``adult.tab``.""" + """Add employment status, sector, SIC and SOC from pinned ``adult.tab``.""" artifacts = _artifact_by_table(stage) adult = normalize_ids( @@ -102,17 +107,18 @@ def add_frs_employment( def derive_frs_employment(person: pd.DataFrame, adult: pd.DataFrame) -> pd.DataFrame: """Return person-indexed employment derivations. - ``empstati``, ``mjobsect``, and ``sic`` are intentionally direct-indexed - so missing source columns fail loudly, matching the incumbent FRS port. - A person is an adult record when their ``person_id`` is in ``adult.tab``; - everyone else is CHILD. + ``empstati``, ``mjobsect``, ``sic`` and ``soc2020`` are intentionally + direct-indexed so missing source columns fail loudly, matching the + incumbent FRS port. A person is an adult record when their ``person_id`` is + in ``adult.tab``; everyone else is CHILD, with no occupation. """ raw = adult.set_index("person_id") aligned = raw.reindex(person["person_id"]) + is_adult = person["person_id"].isin(adult["person_id"]) values = pd.DataFrame(index=person.index) values["employment_status"] = derive_employment_status_from_frs( - aligned["empstati"], person["person_id"].isin(adult["person_id"]) + aligned["empstati"], is_adult ) sector = pd.to_numeric(aligned["mjobsect"], errors="coerce").fillna(0) values["employment_sector"] = ( @@ -125,6 +131,9 @@ def derive_frs_employment(person: pd.DataFrame, adult: pd.DataFrame) -> pd.DataF .astype(int) .to_numpy() ) + values["soc2020_major_group"] = derive_soc2020_major_group_from_frs( + aligned["soc2020"], is_adult + ) return values @@ -164,6 +173,40 @@ def derive_employment_status_from_frs(empstati, is_adult_record) -> np.ndarray: return np.where(adult, adult_status, CHILD_EMPLOYMENT_STATUS).astype(object) +def derive_soc2020_major_group_from_frs(soc2020, is_adult_record) -> np.ndarray: + """Map FRS SOC2020 codes to ``soc2020_major_group``. + + The code is the main job, or the last job for an adult not in work: the FRS + asks the employment questions of everyone who has ever worked (2024-25 + question instructions, details of employment, p. 183; PDF p. 184). + Child-table people are NONE whatever their code. Every adult must carry a + code in ``UK_FRS_SOC2020_MAJOR_GROUP``: a blank or unknown adult code + refuses the build, as EMPSTATI's does, naming the codes but never a count. + """ + + codes = pd.Series( + np.asarray(pd.to_numeric(soc2020, errors="coerce"), dtype="float64") + ) + adult = np.asarray(is_adult_record, dtype=bool) + if adult.shape != codes.shape: + raise ValueError( + "FRS SOC2020 codes and adult-record flags must have the same length." + ) + adult_group = codes.map(UK_FRS_SOC2020_MAJOR_GROUP).to_numpy(dtype=object) + unknown = adult & pd.isna(adult_group) + if unknown.any(): + bad = codes[unknown] + labels = [_code_label(code) for code in sorted(bad.dropna().unique())] + if bad.isna().any(): + labels.append("blank or non-numeric") + raise ValueError( + "FRS adult.tab carries adults with SOC2020 code(s) " + f"{labels} outside UK_FRS_SOC2020_MAJOR_GROUP; map them from the " + "release's data dictionary." + ) + return np.where(adult, adult_group, UK_SOC2020_NO_OCCUPATION).astype(object) + + def _code_label(code: float) -> str: return str(int(code)) if float(code).is_integer() else str(code) 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 a93d395cfb..44babffc2d 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -827,6 +827,7 @@ def _cells( _Cell("person", "employment_status", "string"), _Cell("person", "employment_sector", "string"), _Cell("person", "sic_industry_division", "int64"), + _Cell("person", "soc2020_major_group", "string"), ), "frs_council_tax": (_Cell("household", "council_tax", "float64"),), "frs_disability": ( diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py new file mode 100644 index 0000000000..8254fa56ff --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py @@ -0,0 +1,43 @@ +"""UK occupation codes: the engine's SOC 2020 groups and the codings the build reads.""" + +from __future__ import annotations + +from collections.abc import Mapping +from types import MappingProxyType + +#: The engine's ``soc2020_major_group`` member for a person with no occupation +#: recorded: a child, an adult who has never worked, or an unknown code. +UK_SOC2020_NO_OCCUPATION = "NONE" + +#: The engine's ``soc2020_major_group`` members (policyengine-uk +#: ``SOC2020MajorGroup``) by SOC 2020 major group code, in code order (ONS SOC +#: 2020 Volume 1). +UK_SOC2020_MAJOR_GROUPS: Mapping[int, str] = MappingProxyType( + { + 1: "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS", + 2: "PROFESSIONAL", + 3: "ASSOCIATE_PROFESSIONAL", + 4: "ADMINISTRATIVE_AND_SECRETARIAL", + 5: "SKILLED_TRADES", + 6: "CARING_LEISURE_AND_OTHER_SERVICE", + 7: "SALES_AND_CUSTOMER_SERVICE", + 8: "PROCESS_PLANT_AND_MACHINE_OPERATIVES", + 9: "ELEMENTARY", + } +) + +#: The FRS adult-table ``SOC2020`` coding -> the engine's member: 0 is undefined, +#: and each major group is its code times 1000 (UKDS FRS 2024-25 data +#: dictionary, SN 9563). +UK_FRS_SOC2020_MAJOR_GROUP: Mapping[int, str] = MappingProxyType( + { + 0: UK_SOC2020_NO_OCCUPATION, + **{code * 1000: name for code, name in UK_SOC2020_MAJOR_GROUPS.items()}, + } +) + +__all__ = [ + "UK_FRS_SOC2020_MAJOR_GROUP", + "UK_SOC2020_MAJOR_GROUPS", + "UK_SOC2020_NO_OCCUPATION", +] 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 6ff0d518ad..9a9e435bd4 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 @@ -384,6 +384,7 @@ def __post_init__(self) -> None: "person.salary_sacrifice_asked", "person.salary_sacrifice_reported", "person.sic_industry_division", + "person.soc2020_major_group", "person.stands_as_sole_owner_or_partner_of_company", "person.statutory_paternity_pay", "person.student_loan_balance", diff --git a/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py b/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py new file mode 100644 index 0000000000..e5dc88de35 --- /dev/null +++ b/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py @@ -0,0 +1,23 @@ +"""The SOC 2020 occupation constants against the engine's enum and code map.""" + +from policyengine_uk.variables.household.income.soc2020_major_group import ( + SOC2020_MAJOR_GROUP_CODES, + SOC2020MajorGroup, +) + +from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_MAJOR_GROUPS, + UK_SOC2020_NO_OCCUPATION, +) + + +def test_major_groups_are_the_engine_enum_in_code_order() -> None: + members = list(SOC2020MajorGroup.__members__) + assert members[0] == UK_SOC2020_NO_OCCUPATION + assert members[1:] == list(UK_SOC2020_MAJOR_GROUPS.values()) + + +def test_major_group_codes_are_the_engine_code_map() -> None: + assert dict(SOC2020_MAJOR_GROUP_CODES) == { + name: code for code, name in UK_SOC2020_MAJOR_GROUPS.items() + } diff --git a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py index b7a06ead53..aaabbd1bfa 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py @@ -1659,6 +1659,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_council_tax_band_domain", "uk_uc_deduction_combination_enum_domain", "uk_student_loan_plan_enum_domain", + "uk_soc2020_major_group_enum_domain", "uk_council_tax_band_domain_terminal", "uk_calibration_reference_coverage", "uk_target_surface", diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py index f036c5ba33..81610bc4b3 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py @@ -1080,9 +1080,11 @@ def test_fully_armed_battery_evaluates_gate_for_gate(self) -> None: # path over distinct sub-exempt gains that never cross the exempt # amount, and the release-frame council-tax band check (#1278). # Plus uk_local_brma_enum_domain, the terminal recheck of the area-BRMA - # rewrite (microcosm#1262; its enum_domain binding is stubbed here). - assert len(passed) == 22 + # rewrite (microcosm#1262; its enum_domain binding is stubbed here), and + # the SOC 2020 major group's enum check (microcosm#1490). + assert len(passed) == 23 assert "uk_local_brma_enum_domain" in passed + assert "uk_soc2020_major_group_enum_domain" in passed def test_input_mass_parity_compares_the_release_surface(self) -> None: # The frame carries the spine's WAS property_wealth and the reference diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_employment.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_employment.py index 3b23d9f6dc..e673fc6bdb 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_employment.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_employment.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json import re import numpy as np @@ -13,6 +14,18 @@ FRS_EMPSTATI_EMPLOYMENT_STATUS, derive_employment_status_from_frs, derive_frs_employment, + derive_soc2020_major_group_from_frs, +) +from microcosm.build.uk_runtime.occupation_constants import ( + UK_FRS_SOC2020_MAJOR_GROUP, + UK_SOC2020_NO_OCCUPATION, +) +from microcosm.build.uk_runtime.terminal_gates import UK_ALLOWED_EXTRA_EXPORT_COLUMNS +from test_support.paths import paths_for + +UK_PACKAGE = ( + paths_for("microcosm-build").repository + / "packages/microcosm-build/src/microcosm/build/uk" ) # EMPSTATI ("Adult - Employment Status - ILO definition") value labels in the @@ -59,7 +72,7 @@ def _expected(adult, code): return DATA_DICTIONARY[code][1] if adult else "CHILD" -def test_employment_maps_status_sector_and_sic() -> None: +def test_employment_maps_status_sector_sic_and_soc() -> None: # Person 6 is not in adult.tab (a child-table person), so every adult.tab # column aligns to NaN for them. person = pd.DataFrame({"person_id": [1, 2, 3, 4, 5, 6]}) @@ -69,6 +82,7 @@ def test_employment_maps_status_sector_and_sic() -> None: "empstati": [8, 1.0, 11, 10, 9], "mjobsect": [1, np.nan, 2, 1, 0], "sic": [20, 7, np.nan, 84.9, -5], + "soc2020": [9000, 2000, 0, 4000.0, 1000], } ) @@ -91,6 +105,14 @@ def test_employment_maps_status_sector_and_sic() -> None: "NOT_EMPLOYED", ] assert result["sic_industry_division"].tolist() == [0, 84, 0, 7, 20, 0] + assert result["soc2020_major_group"].tolist() == [ + "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS", + "ADMINISTRATIVE_AND_SECRETARIAL", + "NONE", + "PROFESSIONAL", + "ELEMENTARY", + "NONE", + ] def test_other_inactive_is_not_long_term_disabled() -> None: @@ -152,7 +174,13 @@ def test_unknown_adult_code_fails_the_build(code) -> None: def test_adult_record_with_unknown_or_blank_code_fails_the_stage(code) -> None: person = pd.DataFrame({"person_id": [1, 2]}) adult = pd.DataFrame( - {"person_id": [1, 2], "empstati": [1, code], "mjobsect": [1, 1], "sic": [1, 1]} + { + "person_id": [1, 2], + "empstati": [1, code], + "mjobsect": [1, 1], + "sic": [1, 1], + "soc2020": [1000, 1000], + } ) with pytest.raises(ValueError, match="EMPSTATI"): @@ -228,7 +256,7 @@ def test_stage_marks_adults_by_adult_tab_membership(rows) -> None: ], "empstati": [code for is_adult, code in rows if is_adult], } - ).assign(mjobsect=0, sic=0) + ).assign(mjobsect=0, sic=0, soc2020=0) result = derive_frs_employment(person, adult.iloc[::-1]) @@ -237,12 +265,87 @@ def test_stage_marks_adults_by_adult_tab_membership(rows) -> None: ] -@pytest.mark.parametrize("missing", ["empstati", "mjobsect", "sic"]) +@pytest.mark.parametrize("missing", ["empstati", "mjobsect", "sic", "soc2020"]) def test_employment_missing_fail_loud_columns_raise(missing: str) -> None: person = pd.DataFrame({"person_id": [1]}) adult = pd.DataFrame( - {"person_id": [1], "empstati": [1], "mjobsect": [1], "sic": [10]} + { + "person_id": [1], + "empstati": [1], + "mjobsect": [1], + "sic": [10], + "soc2020": [2000], + } ).drop(columns=[missing]) with pytest.raises(KeyError): derive_frs_employment(person, adult) + + +# SOC2020 ("Standard Occupational Classification 2020, major group") in the +# UKDS FRS 2024-25 data dictionary (SN 9563, adult table): 0 undefined, then +# the nine major groups as 1000-9000. +SOC_CODES = [0, *range(1000, 10000, 1000)] + + +@pytest.mark.parametrize("code", SOC_CODES) +def test_each_soc_code_maps_to_its_major_group(code) -> None: + expected = "NONE" if code == 0 else UK_FRS_SOC2020_MAJOR_GROUP[code] + assert derive_soc2020_major_group_from_frs([code], [True]).tolist() == [expected] + # A child-table person has no occupation whatever the aligned value. + assert derive_soc2020_major_group_from_frs([code], [False]).tolist() == ["NONE"] + + +def test_child_rows_have_no_occupation_even_when_blank() -> None: + result = derive_soc2020_major_group_from_frs([np.nan, -1, 1500], [False] * 3) + assert result.tolist() == [UK_SOC2020_NO_OCCUPATION] * 3 + + +@pytest.mark.parametrize("code", [-1, 1, 1500, 10000, 9000.5, np.nan, "x"]) +def test_unknown_adult_soc_code_fails_the_build(code) -> None: + with pytest.raises(ValueError, match="SOC2020"): + derive_soc2020_major_group_from_frs([1000, code], [True, True]) + + +def test_unknown_soc_message_names_codes_and_prints_no_count() -> None: + with pytest.raises(ValueError) as error: + derive_soc2020_major_group_from_frs([1500, 1500, np.nan], [True] * 3) + message = str(error.value) + assert "['1500', 'blank or non-numeric']" in message + assert _digits_outside_code_list(message.replace("SOC2020", "SOC")) == [] + + +def test_soc_mismatched_lengths_fail() -> None: + with pytest.raises(ValueError, match="same length"): + derive_soc2020_major_group_from_frs([1000, 2000], [True]) + + +@given( + st.lists( + st.one_of( + st.tuples(st.just(True), st.sampled_from(SOC_CODES)), + st.tuples( + st.just(False), st.one_of(st.just(np.nan), st.integers(-9, 99999)) + ), + ), + max_size=60, + ) +) +def test_each_soc_row_maps_on_its_own(rows) -> None: + result = derive_soc2020_major_group_from_frs( + [code for _, code in rows], [adult for adult, _ in rows] + ) + assert result.tolist() == [ + UK_FRS_SOC2020_MAJOR_GROUP[code] if adult else "NONE" for adult, code in rows + ] + + +def test_gates_check_the_occupation_domain_and_export_the_column() -> None: + gates = json.loads((UK_PACKAGE / "gates.json").read_text(encoding="utf-8")) + by_id = {gate["id"]: gate for gate in gates["gates"]} + enum = by_id["uk_soc2020_major_group_enum_domain"] + assert (enum["gate"], enum["phase"]) == ("enum_domain", "terminal") + assert enum["parameters"]["columns"] == ["soc2020_major_group"] + exported = by_id["uk_export_surface"]["parameters"]["allowed_extra_columns"] + assert "person.soc2020_major_group" in exported + assert "person.soc2020_major_group" in UK_ALLOWED_EXTRA_EXPORT_COLUMNS diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_legacy_proxies.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_legacy_proxies.py index 3a05e259b4..8b8b62448b 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_legacy_proxies.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_legacy_proxies.py @@ -59,7 +59,13 @@ def test_esa_proxies_read_only_the_sick_or_disabled_codes(empstati) -> None: status = derive_frs_employment( pd.DataFrame({"person_id": [1]}), pd.DataFrame( - {"person_id": [1], "empstati": [empstati], "mjobsect": [0], "sic": [0]} + { + "person_id": [1], + "empstati": [empstati], + "mjobsect": [0], + "sic": [0], + "soc2020": [0], + } ), )["employment_status"] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py index fd06afd203..63c6adca84 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py @@ -292,6 +292,7 @@ def _fixture_tables() -> dict[str, list[dict[str, object]]]: "CONVBL": 2, "MJOBSECT": 1, "SIC": 84, + "SOC2020": 4000, "FTED": 2, "TYPEED2": 0, "EDUCQUAL": 17, diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py new file mode 100644 index 0000000000..a642c8e223 --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py @@ -0,0 +1,40 @@ +"""The SOC 2020 occupation constants and the views derived from them agree.""" + +from __future__ import annotations + +import pytest + +from microcosm.build.uk_runtime import frs_employment +from microcosm.build.uk_runtime.occupation_constants import ( + UK_FRS_SOC2020_MAJOR_GROUP, + UK_SOC2020_MAJOR_GROUPS, + UK_SOC2020_NO_OCCUPATION, +) + + +def test_major_groups_are_codes_one_to_nine_in_order() -> None: + assert list(UK_SOC2020_MAJOR_GROUPS) == list(range(1, 10)) + names = list(UK_SOC2020_MAJOR_GROUPS.values()) + assert len(set(names)) == len(names) == 9 + assert UK_SOC2020_NO_OCCUPATION == "NONE" + assert UK_SOC2020_NO_OCCUPATION not in names + + +def test_the_frs_view_is_derived_from_the_major_groups() -> None: + assert dict(UK_FRS_SOC2020_MAJOR_GROUP) == { + 0: UK_SOC2020_NO_OCCUPATION, + **{code * 1000: name for code, name in UK_SOC2020_MAJOR_GROUPS.items()}, + } + + +def test_the_employment_stage_reads_the_shared_frs_view() -> None: + assert frs_employment.UK_FRS_SOC2020_MAJOR_GROUP is UK_FRS_SOC2020_MAJOR_GROUP + assert "soc2020_major_group" in frs_employment.FRS_EMPLOYMENT_OUTPUT_COLUMNS + + +@pytest.mark.parametrize( + "mapping", [UK_SOC2020_MAJOR_GROUPS, UK_FRS_SOC2020_MAJOR_GROUP] +) +def test_the_code_tables_are_immutable(mapping) -> None: + with pytest.raises(TypeError): + mapping[10] = "OTHER" # type: ignore[index] diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index e794b3006c..620516d8a0 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -475,13 +475,13 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: # fingerprint derives from the manifest digest. Editing the spec moves all # three here in the same reviewed change. _UK_GATE_BATTERY_POLICY_SHA256 = ( - "7c20944f06349bca285eb3f8e8e696cfef99c356b7685d990e36f9e53c019753" + "829eaae1a12e19f0c41c737bea0dbdda6448637e977b008bad9ca5c3db357200" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "d57afaa831f0599d53b23b653119f4508eecf9ceb97aa7f1d16197a93824cd3c" + "01abc259f99ecdd73bd636102b32482f1f41dc557a5f0bf23d930348c75a8c8d" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "6b9c4d1cfb177629672c7ee9daa659422261b2e0c15b8715ca184b3d3bdc4ff6" + "215c0fab9e2c77b415633f8f9292a5ff20839662274df7d6d7f1e126417badde" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -506,6 +506,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_council_tax_band_domain": "enum_domain", "uk_uc_deduction_combination_enum_domain": "enum_domain", "uk_student_loan_plan_enum_domain": "enum_domain", + "uk_soc2020_major_group_enum_domain": "enum_domain", "uk_council_tax_band_domain_terminal": "enum_domain", "uk_target_surface": "target_surface", "uk_target_fit": "target_fit", @@ -616,6 +617,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_council_tax_band_domain": ("enum_domain", "transferred"), "uk_uc_deduction_combination_enum_domain": ("enum_domain", "terminal"), "uk_student_loan_plan_enum_domain": ("enum_domain", "terminal"), + "uk_soc2020_major_group_enum_domain": ("enum_domain", "terminal"), "uk_council_tax_band_domain_terminal": ("enum_domain", "terminal"), "uk_calibration_reference_coverage": ( "calibration_reference_coverage", @@ -995,6 +997,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: "uk_release_input_coverage", "uk_release_input_coverage_manifest_current", "uk_student_loan_plan_enum_domain", + "uk_soc2020_major_group_enum_domain", "uk_council_tax_band_domain_terminal", "uk_support", "uk_take_up_signal", @@ -1022,10 +1025,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: }, "release_cut": { "gates_manifest_sha256": ( - "c7d6169e6c2516274d3635937c0965f405ad0a02cd821c17bc246c11f82b3a8c" + "fc2f2669d2c73f8a50df9fbf8d42df2cb1e05142b531ef16409445f938547278" ), "policy_sha256": ( - "606a841fca55d7936b7c15a10305582eba11b1a67c4da5248b97c4fa7ff721e5" + "9fa54cd666e8768404729d349855636a13026a0a719164f4f83ec5e68d98620e" ), }, } diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index fb30959394..aac1d19e05 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -224,13 +224,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 = ( - "7c20944f06349bca285eb3f8e8e696cfef99c356b7685d990e36f9e53c019753" + "829eaae1a12e19f0c41c737bea0dbdda6448637e977b008bad9ca5c3db357200" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "d57afaa831f0599d53b23b653119f4508eecf9ceb97aa7f1d16197a93824cd3c" + "01abc259f99ecdd73bd636102b32482f1f41dc557a5f0bf23d930348c75a8c8d" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "6b9c4d1cfb177629672c7ee9daa659422261b2e0c15b8715ca184b3d3bdc4ff6" + "215c0fab9e2c77b415633f8f9292a5ff20839662274df7d6d7f1e126417badde" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "f246388de42654dd68dbbb40c42282001b5b0a8bf48976162bcb1199085cb1d3" @@ -463,6 +463,11 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "terminal", "enum_domain", ), + "uk_soc2020_major_group_enum_domain": ( + "enum_domain", + "terminal", + "enum_domain", + ), "uk_council_tax_band_domain_terminal": ( "enum_domain", "terminal", diff --git a/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py b/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py index 83dcf87e0c..7830b3d739 100644 --- a/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py +++ b/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py @@ -454,15 +454,6 @@ "microcosm#1439 stores the status and retires the encoding (for María's " "signature)." ), - "soc2020_major_group": ( - "The SOC 2020 major group of the person's main job, or of their last " - "job if they are not in work (policyengine-uk 2.173.0, " - "policyengine-uk#2858). The build carries no occupation yet, so every " - "person takes NONE ('No occupation recorded'), and no engine formula " - "reads it. microcosm#1490 carries the FRS major group from " - "frs_employment, redraws it on the SPI channel and removes this entry " - "(for María's signature)." - ), "soc2020_sub_major_group": ( "The SOC 2020 sub-major group of the same job (policyengine-uk " "2.173.0). The FRS codes the major group only, so the sub-major group " diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md index 149f550156..59bc77cc82 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md @@ -1,6 +1,6 @@ # UK spine parity string normalization -The unchanged legacy transforms retain these 29 textual table columns as +The unchanged legacy transforms retain these 30 textual table columns as pandas `object`. The frozen graph dtype token `string` is specified by interface-freeze amendment 10 as pandas `StringDtype(storage="python")`. Before computing the legacy oracle's `uk_frame_content_identity` (live, @@ -8,6 +8,6 @@ in `legacy_oracle_identity`), exactly this audited surface is cast to that dtype. No values, row order, column order, weights, strata, mass records, or metadata change. -- `person`: `gender`, `marital_status`, `employment_status`, `employment_sector`, `aa_category`, `dla_sc_category`, `dla_m_category`, `pip_m_category`, `pip_dl_category`, `current_education`, `highest_education`, `person_support_channel`, `student_loan_plan`, `relationship_to_head`, `ons_family_role`, `capital_gains_asset_type`, `company_car_fuel_type`, `car_fuel_type`, `car_first_registration_date` +- `person`: `gender`, `marital_status`, `employment_status`, `employment_sector`, `soc2020_major_group`, `aa_category`, `dla_sc_category`, `dla_m_category`, `pip_m_category`, `pip_dl_category`, `current_education`, `highest_education`, `person_support_channel`, `student_loan_plan`, `relationship_to_head`, `ons_family_role`, `capital_gains_asset_type`, `company_car_fuel_type`, `car_fuel_type`, `car_first_registration_date` - `benunit`: `benunit_support_channel`, `uc_deduction_combination` - `household`: `region`, `tenure_type`, `accommodation_type`, `council_tax_band`, `brma`, `household_support_channel`, `source_household_key`, `ons_household_type` 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 a3ce21bd92..d9b385a0c4 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 @@ -1367,8 +1367,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" }, @@ -1593,8 +1593,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" }, @@ -1712,8 +1712,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" } @@ -1722,7 +1722,7 @@ "nonnegative_outputs": [ "sic_industry_division" ], - "notes": "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. mjobsect and sic are direct-indexed and fail loudly if absent.", + "notes": "Ports FRS employment derivations. empstati codes 1-11 each map to the status their UKDS SN 9563 adult-table data-dictionary label names, as uk-data#526 does: 11 (Other Inactive) is OTHER_INACTIVE and only 9 (Permanently sick/disabled) is LONG_TERM_DISABLED. People outside adult.tab are CHILD; an adult with a blank or unknown code refuses the build. SOC2020 codes the SOC 2020 major group as 1000-9000 (0 undefined) and maps to policyengine-uk's SOC2020MajorGroup names (occupation_constants); it is the main job, or the last job for an adult not in work, since the FRS asks the employment questions of everyone who has ever worked (2024-25 question instructions, details of employment, p. 183; PDF p. 184). People outside adult.tab are NONE, and an adult with a blank or unknown SOC2020 code refuses the build (microcosm#1490). mjobsect, sic and soc2020 are direct-indexed and fail loudly if absent.", "operations": [ { "delimiter": "\t", @@ -1734,13 +1734,14 @@ }, { "kind": "map_coded_amounts", - "scope": "empstati employment status, mjobsect sector, and raw SIC division" + "scope": "empstati employment status, mjobsect sector, raw SIC division, and SOC2020 major group" } ], "outputs": [ "employment_status", "employment_sector", - "sic_industry_division" + "sic_industry_division", + "soc2020_major_group" ], "rewrites": [], "source": "Department for Work and Pensions Family Resources Survey 2024-25, UK Data Service SN 9563, DOI 10.5255/UKDA-SN-9563-1; local licensed 2024_25 tabs.", @@ -1755,8 +1756,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" }, @@ -1973,8 +1974,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" } @@ -2095,8 +2096,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" }, @@ -2337,8 +2338,8 @@ "locator": "adult.tab", "role": "frs_table", "runtime_sha256_required": true, - "sha256": "20d3343a77d6896cea4b786568b8fc5d869b5bf8594360d610ce9e85a63fd271", - "size_bytes": 35366, + "sha256": "621ccf8d4b91fd89c7b66ff7ed221786c5e634d4ab63fd32c253d8fa686b66f9", + "size_bytes": 36049, "table": "adult", "vintage": "synthetic-h2" }, diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/adult.tab b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/adult.tab index 53cfbca96c..a998a6e2be 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/adult.tab +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/frs_raw/adult.tab @@ -1,136 +1,136 @@ -SERNUM BENUNIT PERSON AGE80 AGE SEX TOTHOURS HRPID UPERSON RELHRP R01 R02 R03 R04 R05 R06 R07 R08 R09 R10 R11 R12 R13 R14 MARITAL EMPSTATI SAMESIT SRENTAMT CONVBL SDEMP01 SDEMP02 SDEMP03 SDEMP04 SDEMP05 SDEMP06 SDEMP07 SDEMP08 SDEMP09 SDEMP10 SDEMP11 SDEMP12 SELFDEMP WORKING JOBAWAY NUMJOB2 CURRJOBM PREVJOBM LSTWRK1 LSTWRK2 LSTYR RETIRE RETIRE1 MJOBSECT SIC FTED TYPEED2 EDUCQUAL TRAINEE EMAAMT CHEMAAMT INEARNS SEINCAM2 MNTUS1 MNTUSAM1 MNTAMT1 MNTAMT2 CVPAY ROYYR1 ROYYR2 ROYYR3 ROYYR4 ALLPAY2 ALLPAY3 ALLPAY4 CHAMTERN CHAMTTST APAMT APDAMT ALIUS ALUAMT ALIAMT PAREAMT REDAMT SLREPAMT SLOS EDUCLEFT SSPADJ SMPADJ SPPADJ TUBORR ACCSSAMT ACCSSPD SPCREG1 SPCREG2 GRTDIR1 GRTDIR2 HEARTVAL HOURTOT -1 1 1 0 80 2 21 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 11 2 0 2 2 0.0 0.0 101.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -2 1 1 0 22 1 22 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 14 2 1 12 2 0 3 2 0.0 0.0 102.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -3 1 1 0 23 2 23 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 15 2 2 13 2 0 4 2 0.0 0.0 103.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -4 1 1 0 24 1 24 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 2 1 14 2 0 5 2 0.0 0.0 104.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -5 1 1 0 25 2 25 1 1 7 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 15 2 0 6 2 0.0 0.0 105.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -6 1 1 0 26 1 26 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18 2 1 16 2 0 7 2 0.0 0.0 106.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -7 1 1 0 27 2 27 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 2 2 17 2 0 8 2 0.0 0.0 107.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -8 1 1 0 28 1 28 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20 2 1 18 2 0 9 2 0.0 0.0 108.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -9 1 1 0 29 2 29 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 21 2 2 19 2 0 10 2 0.0 0.0 109.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -10 1 1 0 30 1 30 1 1 7 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 1 20 2 0 11 2 0.0 0.0 110.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -11 1 1 0 31 2 31 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 23 2 2 21 2 0 12 2 0.0 0.0 111.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -12 1 1 0 32 1 32 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 24 2 1 22 2 0 13 2 0.0 0.0 112.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -13 1 1 0 33 2 33 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 25 1 2 2 23 2 0 14 2 0.0 0.0 113.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -14 1 1 0 34 1 34 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 24 2 0 15 2 0.0 0.0 114.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -15 1 1 0 35 2 35 1 1 7 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 27 2 2 25 2 0 16 2 0.0 0.0 115.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -16 1 1 0 36 1 36 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 28 2 1 26 2 0 17 2 0.0 0.0 116.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -17 1 1 0 37 2 37 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 2 2 27 2 0 18 2 0.0 0.0 117.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -18 1 1 0 38 1 38 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 30 2 1 28 2 0 1 2 0.0 0.0 118.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -19 1 1 0 39 2 39 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 2 29 2 0 2 2 0.0 0.0 119.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -20 1 1 0 40 1 40 1 1 7 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 32 2 1 30 2 0 3 2 0.0 0.0 120.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -21 1 1 0 41 2 41 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 33 2 2 31 2 0 4 2 0.0 0.0 121.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 -22 1 1 0 42 1 42 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 34 2 1 32 2 0 5 2 0.0 0.0 122.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -23 1 1 0 43 2 43 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 33 2 0 6 2 0.0 0.0 123.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -24 1 1 0 44 1 44 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 36 2 1 34 2 0 7 2 0.0 0.0 124.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -25 1 1 0 45 2 20 1 1 7 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 37 2 2 35 2 0 8 2 0.0 0.0 125.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -26 1 1 0 46 1 21 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 38 1 3 1 36 2 0 9 2 0.0 0.0 126.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -27 1 1 0 47 2 22 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 39 2 2 37 2 0 10 2 0.0 0.0 127.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -28 1 1 0 48 1 23 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 38 2 0 11 2 0.0 0.0 128.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -29 1 1 0 49 2 24 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 41 2 2 39 2 0 12 2 0.0 0.0 129.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -30 1 1 0 50 1 25 1 1 7 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 42 2 1 40 2 0 13 2 0.0 0.0 130.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -31 1 1 0 51 2 26 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 43 2 2 41 2 0 14 2 0.0 0.0 131.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -32 1 1 0 52 1 27 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 42 2 0 15 2 0.0 0.0 132.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -33 1 1 0 53 2 28 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 45 2 2 43 2 0 16 2 0.0 0.0 133.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -34 1 1 0 54 1 29 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 46 2 1 44 2 0 17 2 0.0 0.0 134.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -35 1 1 0 55 2 30 1 1 7 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 47 2 2 45 2 0 18 2 0.0 0.0 135.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 -36 1 1 0 56 1 31 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 48 2 1 46 2 0 1 2 0.0 0.0 136.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -37 1 1 0 57 2 32 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 47 2 0 2 2 0.0 0.0 137.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -38 1 1 0 58 1 33 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 50 2 1 48 2 0 3 2 0.0 0.0 138.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -39 1 1 0 59 2 34 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 51 1 4 2 49 2 0 4 2 0.0 0.0 139.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -40 1 1 0 60 1 35 1 1 7 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 52 2 1 50 2 0 5 2 0.0 0.0 140.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -41 1 1 0 61 2 36 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 51 2 0 6 2 0.0 0.0 141.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -42 1 1 0 62 1 37 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 54 2 1 52 2 0 7 2 0.0 0.0 142.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -43 1 1 0 63 2 38 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 55 2 2 53 2 0 8 2 0.0 0.0 143.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -44 1 1 0 64 1 39 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 56 2 1 54 2 0 9 2 0.0 0.0 144.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -45 1 1 0 65 2 40 1 1 7 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 57 2 2 55 2 0 10 2 0.0 0.0 145.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -46 1 1 0 66 1 41 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 56 2 0 11 2 0.0 0.0 146.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -47 1 1 0 67 2 42 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 59 2 2 57 2 0 12 2 0.0 0.0 147.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -48 1 1 0 68 1 43 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 60 2 1 58 2 0 13 2 0.0 0.0 148.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -49 1 1 0 69 2 44 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 61 2 2 59 2 0 14 2 0.0 0.0 149.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -50 1 1 0 70 1 20 1 1 7 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 1 60 2 0 15 2 0.0 0.0 150.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -51 1 1 0 71 2 21 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 63 2 2 61 2 0 16 2 0.0 0.0 151.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -52 1 1 0 72 1 22 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 64 1 5 1 62 2 0 17 2 0.0 0.0 152.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -53 1 1 0 73 2 23 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 65 2 2 63 2 0 18 2 0.0 0.0 153.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -54 1 1 0 74 1 24 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 66 2 1 64 2 0 1 2 0.0 0.0 154.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -55 1 1 0 20 2 25 1 1 7 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 65 2 0 2 2 0.0 0.0 155.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -56 1 1 0 21 1 26 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 68 2 1 66 2 0 3 2 0.0 0.0 156.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 -57 1 1 0 22 2 27 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 69 2 2 67 2 0 4 2 0.0 0.0 157.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -58 1 1 0 23 1 28 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 70 2 1 68 2 0 5 2 0.0 0.0 158.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -59 1 1 0 24 2 29 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 2 69 2 0 6 2 0.0 0.0 159.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -60 1 1 0 25 1 30 1 1 7 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 72 2 1 70 2 0 7 2 0.0 0.0 160.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -61 1 1 0 26 2 31 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 73 2 2 71 2 0 8 2 0.0 0.0 161.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -62 1 1 0 27 1 32 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 74 2 1 72 2 0 9 2 0.0 0.0 162.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -63 1 1 0 28 2 33 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 75 2 2 73 2 0 10 2 0.0 0.0 163.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -64 1 1 0 29 1 34 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 74 2 0 11 2 0.0 0.0 164.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -65 1 1 0 30 2 35 1 1 7 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 77 1 6 2 75 2 0 12 2 0.0 0.0 165.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -66 1 1 0 31 1 36 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 78 2 1 76 2 0 13 2 0.0 0.0 166.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -67 1 1 0 32 2 37 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 79 2 2 77 2 0 14 2 0.0 0.0 167.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -68 1 1 0 33 1 38 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 78 2 0 15 2 0.0 0.0 168.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -69 1 1 0 34 2 39 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 81 2 2 79 2 0 16 2 0.0 0.0 169.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -70 1 1 0 35 1 40 1 1 7 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 82 2 1 80 2 0 17 2 0.0 0.0 170.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 -71 1 1 0 36 2 41 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 83 2 2 81 2 0 18 2 0.0 0.0 171.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -72 1 1 0 37 1 42 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 84 2 1 82 2 0 1 2 0.0 0.0 172.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -73 1 1 0 38 2 43 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 83 2 0 2 2 0.0 0.0 173.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -74 1 1 0 39 1 44 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 86 2 1 84 2 0 3 2 0.0 0.0 174.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -75 1 1 0 40 2 20 1 1 7 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 87 2 2 85 2 0 4 2 0.0 0.0 175.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -76 1 1 0 41 1 21 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 88 2 1 86 2 0 5 2 0.0 0.0 176.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -77 1 1 0 42 2 22 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 87 2 0 6 2 0.0 0.0 177.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -78 1 1 0 43 1 23 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 90 1 7 1 88 2 0 7 2 0.0 0.0 178.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -79 1 1 0 44 2 24 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 91 2 2 89 2 0 8 2 0.0 0.0 179.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -80 1 1 0 45 1 25 1 1 7 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 92 2 1 10 2 0 9 2 0.0 0.0 180.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -81 1 1 0 46 2 26 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 93 2 2 11 2 0 10 2 0.0 0.0 181.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -82 1 1 0 47 1 27 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 1 12 2 0 11 2 0.0 0.0 182.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -83 1 1 0 48 2 28 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 95 2 2 13 2 0 12 2 0.0 0.0 183.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -84 1 1 0 49 1 29 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 96 2 1 14 2 0 13 2 0.0 0.0 184.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -85 1 1 0 50 2 30 1 1 7 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 97 2 2 15 2 0 14 2 0.0 0.0 185.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -86 1 1 0 51 1 31 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 16 2 0 15 2 0.0 0.0 186.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -87 1 1 0 52 2 32 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 99 2 2 17 2 0 16 2 0.0 0.0 187.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -88 1 1 0 53 1 33 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 2 1 18 2 0 17 2 0.0 0.0 188.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -89 1 1 0 54 2 34 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 101 2 2 19 2 0 18 2 0.0 0.0 189.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -90 1 1 0 55 1 35 1 1 7 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 102 2 1 20 2 0 1 2 0.0 0.0 190.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -91 1 1 0 56 2 36 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 1 8 2 21 2 0 2 2 0.0 0.0 191.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 -92 1 1 0 57 1 37 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 104 2 1 22 2 0 3 2 0.0 0.0 192.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -93 1 1 0 58 2 38 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 105 2 2 23 2 0 4 2 0.0 0.0 193.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -94 1 1 0 59 1 39 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 106 2 1 24 2 0 5 2 0.0 0.0 194.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -95 1 1 0 60 2 40 1 1 7 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 25 2 0 6 2 0.0 0.0 195.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -96 1 1 0 61 1 41 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 108 2 1 26 2 0 7 2 0.0 0.0 196.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -97 1 1 0 62 2 42 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 109 2 2 27 2 0 8 2 0.0 0.0 197.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -98 1 1 0 63 1 43 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 110 2 1 28 2 0 9 2 0.0 0.0 198.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -99 1 1 0 64 2 44 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 111 2 2 29 2 0 10 2 0.0 0.0 199.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -100 1 1 0 65 1 20 1 1 7 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 30 2 0 11 2 0.0 0.0 200.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -101 1 1 0 66 2 21 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 13 2 2 31 2 0 12 2 0.0 0.0 201.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -102 1 1 0 67 1 22 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 2 1 32 2 0 13 2 0.0 0.0 202.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -103 1 1 0 68 2 23 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 2 2 33 2 0 14 2 0.0 0.0 203.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -104 1 1 0 69 1 24 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 1 9 1 34 2 0 15 2 0.0 0.0 204.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -105 1 1 0 70 2 25 1 1 7 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 17 2 2 35 2 0 16 2 0.0 0.0 205.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 -106 1 1 0 71 1 26 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 18 2 1 36 2 0 17 2 0.0 0.0 206.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -107 1 1 0 72 2 27 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 19 2 2 37 2 0 18 2 0.0 0.0 207.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -108 1 1 0 73 1 28 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20 2 1 38 2 0 1 2 0.0 0.0 208.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -109 1 1 0 74 2 29 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 39 2 0 2 2 0.0 0.0 209.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -110 1 1 0 20 1 30 1 1 7 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 22 2 1 40 2 0 3 2 0.0 0.0 210.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -111 1 1 0 21 2 31 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 2 2 41 2 0 4 2 0.0 0.0 211.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -112 1 1 0 22 1 32 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 24 2 1 42 2 0 5 2 0.0 0.0 212.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -113 1 1 0 23 2 33 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 43 2 0 6 2 0.0 0.0 213.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -114 1 1 0 24 1 34 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 26 2 1 44 2 0 7 2 0.0 0.0 214.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -115 1 1 0 25 2 35 1 1 7 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 27 2 2 45 2 0 8 2 0.0 0.0 215.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -116 1 1 0 26 1 36 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 28 2 1 46 2 0 9 2 0.0 0.0 216.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -117 1 1 0 27 2 37 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 1 10 2 47 2 0 10 2 0.0 0.0 217.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -118 1 1 0 28 1 38 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 48 2 0 11 2 0.0 0.0 218.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -119 1 1 0 29 2 39 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 31 2 2 49 2 0 12 2 0.0 0.0 219.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -120 1 1 0 30 1 40 1 1 7 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 32 2 1 50 2 0 13 2 0.0 0.0 220.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -121 1 1 0 31 2 41 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 33 2 2 51 2 0 14 2 0.0 0.0 221.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -122 1 1 0 32 1 42 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 1 52 2 0 15 2 0.0 0.0 222.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -123 1 1 0 33 2 43 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 35 2 2 53 2 0 16 2 0.0 0.0 223.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -124 1 1 0 34 1 44 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 36 2 1 54 2 0 17 2 0.0 0.0 224.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -125 1 1 0 35 2 20 1 1 7 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 37 2 2 55 2 0 18 2 0.0 0.0 225.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -126 1 1 0 36 1 21 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 38 2 1 56 2 0 1 2 0.0 0.0 226.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 -127 1 1 0 37 2 22 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 57 2 0 2 2 0.0 0.0 227.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -128 1 1 0 38 1 23 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 40 2 1 58 2 0 3 2 0.0 0.0 228.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -129 1 1 0 39 2 24 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 41 2 2 59 2 0 4 2 0.0 0.0 229.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -130 1 1 0 40 1 25 1 1 7 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 42 1 11 1 60 2 0 5 2 0.0 0.0 230.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 -131 1 1 0 41 2 26 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 2 61 2 0 6 2 0.0 0.0 231.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 -132 1 1 0 42 1 27 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 44 2 1 62 2 0 7 2 0.0 0.0 232.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -133 1 1 0 43 2 28 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 45 2 2 63 2 0 8 2 0.0 0.0 233.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 -134 1 1 0 44 1 29 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 46 2 1 64 2 0 9 2 0.0 0.0 234.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 -135 1 1 0 45 2 30 1 1 7 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 47 2 2 65 2 0 10 2 0.0 0.0 235.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +SERNUM BENUNIT PERSON AGE80 AGE SEX TOTHOURS HRPID UPERSON RELHRP R01 R02 R03 R04 R05 R06 R07 R08 R09 R10 R11 R12 R13 R14 MARITAL EMPSTATI SAMESIT SRENTAMT CONVBL SDEMP01 SDEMP02 SDEMP03 SDEMP04 SDEMP05 SDEMP06 SDEMP07 SDEMP08 SDEMP09 SDEMP10 SDEMP11 SDEMP12 SELFDEMP WORKING JOBAWAY NUMJOB2 CURRJOBM PREVJOBM LSTWRK1 LSTWRK2 LSTYR RETIRE RETIRE1 MJOBSECT SIC SOC2020 FTED TYPEED2 EDUCQUAL TRAINEE EMAAMT CHEMAAMT INEARNS SEINCAM2 MNTUS1 MNTUSAM1 MNTAMT1 MNTAMT2 CVPAY ROYYR1 ROYYR2 ROYYR3 ROYYR4 ALLPAY2 ALLPAY3 ALLPAY4 CHAMTERN CHAMTTST APAMT APDAMT ALIUS ALUAMT ALIAMT PAREAMT REDAMT SLREPAMT SLOS EDUCLEFT SSPADJ SMPADJ SPPADJ TUBORR ACCSSAMT ACCSSPD SPCREG1 SPCREG2 GRTDIR1 GRTDIR2 HEARTVAL HOURTOT +1 1 1 0 80 2 21 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 11 2000 2 0 2 2 0.0 0.0 101.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +2 1 1 0 22 1 22 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 14 2 1 12 3000 2 0 3 2 0.0 0.0 102.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +3 1 1 0 23 2 23 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 15 2 2 13 4000 2 0 4 2 0.0 0.0 103.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +4 1 1 0 24 1 24 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 16 2 1 14 5000 2 0 5 2 0.0 0.0 104.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +5 1 1 0 25 2 25 1 1 7 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 15 6000 2 0 6 2 0.0 0.0 105.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +6 1 1 0 26 1 26 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 18 2 1 16 7000 2 0 7 2 0.0 0.0 106.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +7 1 1 0 27 2 27 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 2 2 17 8000 2 0 8 2 0.0 0.0 107.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +8 1 1 0 28 1 28 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20 2 1 18 9000 2 0 9 2 0.0 0.0 108.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +9 1 1 0 29 2 29 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 21 2 2 19 1000 2 0 10 2 0.0 0.0 109.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +10 1 1 0 30 1 30 1 1 7 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 1 20 2000 2 0 11 2 0.0 0.0 110.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +11 1 1 0 31 2 31 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 23 2 2 21 3000 2 0 12 2 0.0 0.0 111.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +12 1 1 0 32 1 32 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 24 2 1 22 4000 2 0 13 2 0.0 0.0 112.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +13 1 1 0 33 2 33 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 25 1 2 2 23 5000 2 0 14 2 0.0 0.0 113.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +14 1 1 0 34 1 34 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 24 6000 2 0 15 2 0.0 0.0 114.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +15 1 1 0 35 2 35 1 1 7 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 27 2 2 25 7000 2 0 16 2 0.0 0.0 115.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +16 1 1 0 36 1 36 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 28 2 1 26 8000 2 0 17 2 0.0 0.0 116.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +17 1 1 0 37 2 37 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 2 2 27 9000 2 0 18 2 0.0 0.0 117.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +18 1 1 0 38 1 38 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 30 2 1 28 1000 2 0 1 2 0.0 0.0 118.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +19 1 1 0 39 2 39 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 2 29 2000 2 0 2 2 0.0 0.0 119.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +20 1 1 0 40 1 40 1 1 7 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 32 2 1 30 3000 2 0 3 2 0.0 0.0 120.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +21 1 1 0 41 2 41 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 33 2 2 31 4000 2 0 4 2 0.0 0.0 121.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 +22 1 1 0 42 1 42 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 34 2 1 32 5000 2 0 5 2 0.0 0.0 122.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +23 1 1 0 43 2 43 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 33 6000 2 0 6 2 0.0 0.0 123.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +24 1 1 0 44 1 44 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 36 2 1 34 7000 2 0 7 2 0.0 0.0 124.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +25 1 1 0 45 2 20 1 1 7 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 37 2 2 35 8000 2 0 8 2 0.0 0.0 125.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +26 1 1 0 46 1 21 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 38 1 3 1 36 9000 2 0 9 2 0.0 0.0 126.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +27 1 1 0 47 2 22 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 39 2 2 37 1000 2 0 10 2 0.0 0.0 127.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +28 1 1 0 48 1 23 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 38 2000 2 0 11 2 0.0 0.0 128.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +29 1 1 0 49 2 24 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 41 2 2 39 3000 2 0 12 2 0.0 0.0 129.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +30 1 1 0 50 1 25 1 1 7 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 42 2 1 40 4000 2 0 13 2 0.0 0.0 130.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +31 1 1 0 51 2 26 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 43 2 2 41 5000 2 0 14 2 0.0 0.0 131.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +32 1 1 0 52 1 27 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 42 6000 2 0 15 2 0.0 0.0 132.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +33 1 1 0 53 2 28 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 45 2 2 43 7000 2 0 16 2 0.0 0.0 133.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +34 1 1 0 54 1 29 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 46 2 1 44 8000 2 0 17 2 0.0 0.0 134.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +35 1 1 0 55 2 30 1 1 7 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 47 2 2 45 9000 2 0 18 2 0.0 0.0 135.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 +36 1 1 0 56 1 31 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 48 2 1 46 1000 2 0 1 2 0.0 0.0 136.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +37 1 1 0 57 2 32 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 47 2000 2 0 2 2 0.0 0.0 137.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +38 1 1 0 58 1 33 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 50 2 1 48 3000 2 0 3 2 0.0 0.0 138.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +39 1 1 0 59 2 34 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 51 1 4 2 49 4000 2 0 4 2 0.0 0.0 139.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +40 1 1 0 60 1 35 1 1 7 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 52 2 1 50 5000 2 0 5 2 0.0 0.0 140.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +41 1 1 0 61 2 36 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 51 6000 2 0 6 2 0.0 0.0 141.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +42 1 1 0 62 1 37 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 54 2 1 52 7000 2 0 7 2 0.0 0.0 142.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +43 1 1 0 63 2 38 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 55 2 2 53 8000 2 0 8 2 0.0 0.0 143.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +44 1 1 0 64 1 39 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 56 2 1 54 9000 2 0 9 2 0.0 0.0 144.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +45 1 1 0 65 2 40 1 1 7 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 57 2 2 55 1000 2 0 10 2 0.0 0.0 145.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +46 1 1 0 66 1 41 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 56 2000 2 0 11 2 0.0 0.0 146.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +47 1 1 0 67 2 42 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 59 2 2 57 3000 2 0 12 2 0.0 0.0 147.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +48 1 1 0 68 1 43 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 60 2 1 58 4000 2 0 13 2 0.0 0.0 148.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +49 1 1 0 69 2 44 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 61 2 2 59 5000 2 0 14 2 0.0 0.0 149.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +50 1 1 0 70 1 20 1 1 7 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 1 60 6000 2 0 15 2 0.0 0.0 150.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +51 1 1 0 71 2 21 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 63 2 2 61 7000 2 0 16 2 0.0 0.0 151.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +52 1 1 0 72 1 22 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 64 1 5 1 62 8000 2 0 17 2 0.0 0.0 152.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +53 1 1 0 73 2 23 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 65 2 2 63 9000 2 0 18 2 0.0 0.0 153.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +54 1 1 0 74 1 24 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 66 2 1 64 1000 2 0 1 2 0.0 0.0 154.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +55 1 1 0 20 2 25 1 1 7 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 65 2000 2 0 2 2 0.0 0.0 155.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +56 1 1 0 21 1 26 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 68 2 1 66 3000 2 0 3 2 0.0 0.0 156.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 +57 1 1 0 22 2 27 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 69 2 2 67 4000 2 0 4 2 0.0 0.0 157.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +58 1 1 0 23 1 28 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 70 2 1 68 5000 2 0 5 2 0.0 0.0 158.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +59 1 1 0 24 2 29 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 2 69 6000 2 0 6 2 0.0 0.0 159.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +60 1 1 0 25 1 30 1 1 7 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 72 2 1 70 7000 2 0 7 2 0.0 0.0 160.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +61 1 1 0 26 2 31 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 73 2 2 71 8000 2 0 8 2 0.0 0.0 161.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +62 1 1 0 27 1 32 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 74 2 1 72 9000 2 0 9 2 0.0 0.0 162.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +63 1 1 0 28 2 33 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 75 2 2 73 1000 2 0 10 2 0.0 0.0 163.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +64 1 1 0 29 1 34 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 74 2000 2 0 11 2 0.0 0.0 164.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +65 1 1 0 30 2 35 1 1 7 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 77 1 6 2 75 3000 2 0 12 2 0.0 0.0 165.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +66 1 1 0 31 1 36 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 78 2 1 76 4000 2 0 13 2 0.0 0.0 166.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +67 1 1 0 32 2 37 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 79 2 2 77 5000 2 0 14 2 0.0 0.0 167.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +68 1 1 0 33 1 38 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 78 6000 2 0 15 2 0.0 0.0 168.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +69 1 1 0 34 2 39 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 81 2 2 79 7000 2 0 16 2 0.0 0.0 169.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +70 1 1 0 35 1 40 1 1 7 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 82 2 1 80 8000 2 0 17 2 0.0 0.0 170.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 +71 1 1 0 36 2 41 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 83 2 2 81 9000 2 0 18 2 0.0 0.0 171.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +72 1 1 0 37 1 42 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 84 2 1 82 1000 2 0 1 2 0.0 0.0 172.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +73 1 1 0 38 2 43 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 83 2000 2 0 2 2 0.0 0.0 173.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +74 1 1 0 39 1 44 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 86 2 1 84 3000 2 0 3 2 0.0 0.0 174.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +75 1 1 0 40 2 20 1 1 7 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 87 2 2 85 4000 2 0 4 2 0.0 0.0 175.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +76 1 1 0 41 1 21 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 88 2 1 86 5000 2 0 5 2 0.0 0.0 176.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +77 1 1 0 42 2 22 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 87 6000 2 0 6 2 0.0 0.0 177.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +78 1 1 0 43 1 23 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 90 1 7 1 88 7000 2 0 7 2 0.0 0.0 178.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +79 1 1 0 44 2 24 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 91 2 2 89 8000 2 0 8 2 0.0 0.0 179.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +80 1 1 0 45 1 25 1 1 7 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 92 2 1 10 9000 2 0 9 2 0.0 0.0 180.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +81 1 1 0 46 2 26 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 93 2 2 11 1000 2 0 10 2 0.0 0.0 181.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +82 1 1 0 47 1 27 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 2 1 12 2000 2 0 11 2 0.0 0.0 182.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +83 1 1 0 48 2 28 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 95 2 2 13 3000 2 0 12 2 0.0 0.0 183.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +84 1 1 0 49 1 29 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 96 2 1 14 4000 2 0 13 2 0.0 0.0 184.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +85 1 1 0 50 2 30 1 1 7 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 97 2 2 15 5000 2 0 14 2 0.0 0.0 185.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +86 1 1 0 51 1 31 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 1 16 6000 2 0 15 2 0.0 0.0 186.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +87 1 1 0 52 2 32 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 99 2 2 17 7000 2 0 16 2 0.0 0.0 187.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +88 1 1 0 53 1 33 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 2 1 18 8000 2 0 17 2 0.0 0.0 188.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +89 1 1 0 54 2 34 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 101 2 2 19 9000 2 0 18 2 0.0 0.0 189.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +90 1 1 0 55 1 35 1 1 7 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 102 2 1 20 1000 2 0 1 2 0.0 0.0 190.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +91 1 1 0 56 2 36 1 1 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 4 1 8 2 21 2000 2 0 2 2 0.0 0.0 191.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 +92 1 1 0 57 1 37 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 104 2 1 22 3000 2 0 3 2 0.0 0.0 192.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +93 1 1 0 58 2 38 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 105 2 2 23 4000 2 0 4 2 0.0 0.0 193.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +94 1 1 0 59 1 39 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 106 2 1 24 5000 2 0 5 2 0.0 0.0 194.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +95 1 1 0 60 2 40 1 1 7 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 25 6000 2 0 6 2 0.0 0.0 195.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +96 1 1 0 61 1 41 1 1 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 108 2 1 26 7000 2 0 7 2 0.0 0.0 196.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +97 1 1 0 62 2 42 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 109 2 2 27 8000 2 0 8 2 0.0 0.0 197.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +98 1 1 0 63 1 43 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 110 2 1 28 9000 2 0 9 2 0.0 0.0 198.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +99 1 1 0 64 2 44 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 111 2 2 29 1000 2 0 10 2 0.0 0.0 199.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +100 1 1 0 65 1 20 1 1 7 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 30 2000 2 0 11 2 0.0 0.0 200.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +101 1 1 0 66 2 21 1 1 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 13 2 2 31 3000 2 0 12 2 0.0 0.0 201.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +102 1 1 0 67 1 22 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 2 1 32 4000 2 0 13 2 0.0 0.0 202.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +103 1 1 0 68 2 23 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 2 2 33 5000 2 0 14 2 0.0 0.0 203.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +104 1 1 0 69 1 24 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 1 9 1 34 6000 2 0 15 2 0.0 0.0 204.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +105 1 1 0 70 2 25 1 1 7 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 17 2 2 35 7000 2 0 16 2 0.0 0.0 205.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 1 1 2.0 3.0 5.0 4 +106 1 1 0 71 1 26 1 1 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 18 2 1 36 8000 2 0 17 2 0.0 0.0 206.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +107 1 1 0 72 2 27 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 19 2 2 37 9000 2 0 18 2 0.0 0.0 207.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +108 1 1 0 73 1 28 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 20 2 1 38 1000 2 0 1 2 0.0 0.0 208.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +109 1 1 0 74 2 29 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 39 2000 2 0 2 2 0.0 0.0 209.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +110 1 1 0 20 1 30 1 1 7 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 22 2 1 40 3000 2 0 3 2 0.0 0.0 210.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +111 1 1 0 21 2 31 1 1 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 23 2 2 41 4000 2 0 4 2 0.0 0.0 211.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +112 1 1 0 22 1 32 1 1 2 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 24 2 1 42 5000 2 0 5 2 0.0 0.0 212.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +113 1 1 0 23 2 33 1 1 3 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 8 2 2 43 6000 2 0 6 2 0.0 0.0 213.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +114 1 1 0 24 1 34 1 1 1 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 26 2 1 44 7000 2 0 7 2 0.0 0.0 214.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +115 1 1 0 25 2 35 1 1 7 2 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 27 2 2 45 8000 2 0 8 2 0.0 0.0 215.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +116 1 1 0 26 1 36 1 1 3 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 28 2 1 46 9000 2 0 9 2 0.0 0.0 216.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +117 1 1 0 27 2 37 1 1 1 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 29 1 10 2 47 1000 2 0 10 2 0.0 0.0 217.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +118 1 1 0 28 1 38 1 1 2 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 1 48 2000 2 0 11 2 0.0 0.0 218.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +119 1 1 0 29 2 39 1 1 3 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 31 2 2 49 3000 2 0 12 2 0.0 0.0 219.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +120 1 1 0 30 1 40 1 1 7 1 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 32 2 1 50 4000 2 0 13 2 0.0 0.0 220.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +121 1 1 0 31 2 41 1 1 2 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 33 2 2 51 5000 2 0 14 2 0.0 0.0 221.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +122 1 1 0 32 1 42 1 1 3 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 1 52 6000 2 0 15 2 0.0 0.0 222.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +123 1 1 0 33 2 43 1 1 1 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 35 2 2 53 7000 2 0 16 2 0.0 0.0 223.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +124 1 1 0 34 1 44 1 1 2 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 36 2 1 54 8000 2 0 17 2 0.0 0.0 224.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +125 1 1 0 35 2 20 1 1 7 3 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 37 2 2 55 9000 2 0 18 2 0.0 0.0 225.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +126 1 1 0 36 1 21 1 1 1 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 38 2 1 56 1000 2 0 1 2 0.0 0.0 226.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 5 +127 1 1 0 37 2 22 1 1 2 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 2 57 2000 2 0 2 2 0.0 0.0 227.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +128 1 1 0 38 1 23 1 1 3 1 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 40 2 1 58 3000 2 0 3 2 0.0 0.0 228.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 16 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +129 1 1 0 39 2 24 1 1 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 41 2 2 59 4000 2 0 4 2 0.0 0.0 229.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 17 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +130 1 1 0 40 1 25 1 1 7 2 3 1 2 3 3 3 3 3 3 3 3 3 3 3 3 3 1 42 1 11 1 60 5000 2 0 5 2 0.0 0.0 230.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 18 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 +131 1 1 0 41 2 26 1 1 3 4 2 1 3 3 3 3 3 3 3 3 3 3 3 3 3 1 8 2 2 61 6000 2 0 6 2 0.0 0.0 231.0 1.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 19 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 5 +132 1 1 0 42 1 27 1 1 1 5 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 44 2 1 62 7000 2 0 7 2 0.0 0.0 232.0 2.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 20 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +133 1 1 0 43 2 28 1 1 2 6 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 45 2 2 63 8000 2 0 8 2 0.0 0.0 233.0 3.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 21 1.0 0.5 0.25 500.0 1.0 52.0 1 2 2.0 3.0 5.0 4 +134 1 1 0 44 1 29 1 1 3 7 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 46 2 1 64 9000 2 0 9 2 0.0 0.0 234.0 4.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 22 1.0 0.5 0.25 500.0 1.0 52.0 2 2 2.0 3.0 5.0 0 +135 1 1 0 45 2 30 1 1 7 1 8 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 47 2 2 65 1000 2 0 10 2 0.0 0.0 235.0 0.0 2 1.0 2.0 1.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 2 3.0 4.0 13.0 20.0 2.0 2 23 1.0 0.5 0.25 500.0 1.0 52.0 2 1 2.0 3.0 5.0 0 diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index 15e557da16..fc44791de7 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -223,6 +223,8 @@ "marital_status", "employment_status", "employment_sector", + # The SOC 2020 major group of the main or last job (microcosm#1490). + "soc2020_major_group", "aa_category", "dla_sc_category", "dla_m_category", @@ -494,6 +496,8 @@ def _frs_tables() -> dict[str, pd.DataFrame]: "RETIRE1": 1 + household_id % 12 if household_id % 13 == 0 else "", "MJOBSECT": 1 + household_id % 2, "SIC": 10 + household_id % 80, + # SOC 2020 major groups 1-9 as the FRS codes them, 1000-9000. + "SOC2020": 1000 * (1 + household_id % 9), "FTED": 2, "TYPEED2": 0, "EDUCQUAL": 1 + household_id % 18, @@ -2122,8 +2126,8 @@ def _normalize_legacy_strings(frame: Frame) -> Frame: for entity, columns in _NORMALIZED_STRING_COLUMNS.items() for column in columns ] - if observed != expected_order or len(observed) != 29: - raise RuntimeError("The legacy normalization audit is not exactly 29 cells.") + if observed != expected_order or len(observed) != 30: + raise RuntimeError("The legacy normalization audit is not exactly 30 cells.") return Frame( tables, frame.schema, From ad492a6c81dbb1cb94718d54e6b07ede39dbf5de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 13:47:39 +0000 Subject: [PATCH 3/7] Redraw the SPI-drawn rows' occupation from their own incomes, with a coherent industry (#1490) The SPI support copies and income band donors are whole FRS households whose claimants and partners then draw SPI incomes, so a drawn row kept its twin's SOC 2020 major group, SIC division and sector, all chosen with the twin's pay. A new person stage, spi_employment_shell, runs after company_cars (so the tape rows' pay is net of car benefits, as FRS pay is) and before spi_housing_shell: - It redraws the major group of every drawn row whose twin had an occupation, or that drew the tape's own PAY or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. - It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, on age, sex, region, employment-status group and employment, self-employment, investment (savings interest plus dividends) and private pension income: what a drawn row holds of its own. The classifier is microcosm-fit's CategoricalClassifier, the declared equal blend of a regularised boosted classifier and a spline logit, drawn at uniforms keyed on person_id. - Each drawn row copies the SIC division and sector of an FRS adult with the drawn group and status group among the 50 nearest on age, incomes and region, falling back to the group and then to everyone. - The receipt records out-of-fold evidence on five household-grouped folds (log loss for the model, each learner and the constant; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps), with counts banded by receipt_counts. A stage-health gate, uk_stage_spi_employment_shell_fit, holds them to declared bounds; it is a population fact check, so the synthetic smoke records it without blocking. Training rows and donors are taken in person_id order, so no draw depends on how the frame orders its rows. On a fixture the knob that caps the boosted learner also turns its early stopping off, since a few households leave classes too thin for the stratified split. The registration moves the derived surfaces: the spec and its packaged projection, the schema branch (every nested block closed), the operation kind, the graph's cells, consumes and reader isolation, the kernel and helper modules, the seed harvest, the gate's registrations and the battery and spine-part digests, the roster pins (53 stages) and the coverage manifest. The H2 fixture is regenerated separately. Co-Authored-By: Claude Opus 5.5 --- .../1490-uk-occupation-spi-redraw.added.md | 3 + .../src/microcosm/build/source_manifest.py | 1 + .../spec_engine/schema/sources.schema.json | 247 +++++++ .../src/microcosm/build/uk/gates.json | 21 + .../uk/release_input_coverage_manifest.json | 50 +- .../src/microcosm/build/uk/source_stages.json | 99 +++ .../src/microcosm/build/uk/spec/sources.yaml | 80 ++ .../build/uk_runtime/battery_bindings.py | 9 + .../build/uk_runtime/calibration_run.py | 1 + .../src/microcosm/build/uk_runtime/graph.py | 30 + .../build/uk_runtime/graph_kernels.py | 21 + .../build/uk_runtime/occupation_constants.py | 66 +- .../build/uk_runtime/spi_employment_shell.py | 685 ++++++++++++++++++ .../microcosm/build/uk_runtime/spine_build.py | 12 +- .../build/uk_runtime/stage_health.py | 108 +++ .../engine_free/shared/test_country_spec.py | 4 +- .../tests/engine_free/uk/test_uk_graph.py | 5 +- .../uk/test_uk_occupation_constants.py | 36 + .../engine_free/uk/test_uk_source_stages.py | 4 + .../uk/test_uk_spi_employment_shell.py | 269 +++++++ .../uk/test_uk_spine_acceptance_receipt.py | 4 + .../src/microcosm/data/contract.py | 13 +- .../tests/engine_free/shared/test_contract.py | 8 +- .../uk_spi_employment_shell.py | 123 ++++ tools/graph_uk_spine_fixture.py | 8 +- 25 files changed, 1868 insertions(+), 39 deletions(-) create mode 100644 changelog.d/1490-uk-occupation-spi-redraw.added.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py create mode 100644 packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py create mode 100644 test_support/microcosm_build/uk_spi_employment_shell.py diff --git a/changelog.d/1490-uk-occupation-spi-redraw.added.md b/changelog.d/1490-uk-occupation-spi-redraw.added.md new file mode 100644 index 0000000000..b6ef208a1c --- /dev/null +++ b/changelog.d/1490-uk-occupation-spi-redraw.added.md @@ -0,0 +1,3 @@ +A new UK spine stage, `spi_employment_shell`, redraws the SOC 2020 major group of the SPI-drawn rows from their own incomes (microcosm#1490). The SPI support copies and income band donors are whole FRS households, so a drawn row kept its twin's occupation, industry and sector, all chosen with the twin's pay. The stage trains on the FRS rows' adults with an occupation and conditions on age, sex, region, employment-status group and employment, self-employment, investment and private pension income. Its classifier is microcosm-fit's new country-agnostic `CategoricalClassifier`: the equal blend of a regularised gradient-boosted classifier and a spline multinomial logit, the learner that held out best on FRS 2024-25. Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group, the same status group and the nearest age and incomes, so occupation and industry stay a pair that occurs. A drawn row whose twin had no occupation and that drew no pay or profit keeps NONE, and FRS rows and undrawn copies are untouched. + +The receipt records held-out evidence on five household-grouped folds (log loss against the constant and each learner, the calibration slope, and occupation-share gaps within pay bands and status groups), and a stage-health gate, `uk_stage_spi_employment_shell_fit`, holds them to declared bounds. Because the stage rewrites `employment_sector`, it moves the `ons.public_sector_employment` calibration target's measured value. diff --git a/packages/microcosm-build/src/microcosm/build/source_manifest.py b/packages/microcosm-build/src/microcosm/build/source_manifest.py index e595c63b26..802083d274 100644 --- a/packages/microcosm-build/src/microcosm/build/source_manifest.py +++ b/packages/microcosm-build/src/microcosm/build/source_manifest.py @@ -165,6 +165,7 @@ "impute_energy_subsidy_to_puf_support", "impute_cell_means", "impute_spi_housing_shell", + "impute_spi_employment_shell", "impute_housing_assistance_to_puf_support", "impute_other_health_insurance_premiums_to_puf_support", "impute_prior_year_income_to_puf_support", 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 91bba03896..4a4b153565 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 @@ -8742,6 +8742,253 @@ } } }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "training_rows", + "rows", + "identity", + "seed", + "occupation", + "industry", + "evidence" + ], + "properties": { + "kind": { + "const": "impute_spi_employment_shell" + }, + "training_rows": { + "type": "string" + }, + "rows": { + "type": "string" + }, + "identity": { + "type": "string" + }, + "seed": { + "type": "integer" + }, + "occupation": { + "type": "object", + "additionalProperties": false, + "required": [ + "target", + "predictors", + "categorical_predictors", + "arcsinh_columns", + "arcsinh_scale", + "boosted", + "logit", + "boosted_weight" + ], + "properties": { + "target": { + "type": "string" + }, + "predictors": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "categorical_predictors": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "arcsinh_columns": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "arcsinh_scale": { + "type": "number", + "exclusiveMinimum": 0 + }, + "boosted": { + "type": "object", + "additionalProperties": false, + "required": [ + "learning_rate", + "max_leaf_nodes", + "min_samples_leaf", + "l2_regularization", + "early_stopping", + "validation_fraction", + "n_iter_no_change", + "max_iter" + ], + "properties": { + "learning_rate": { + "type": "number", + "exclusiveMinimum": 0 + }, + "max_leaf_nodes": { + "type": "integer", + "minimum": 2 + }, + "min_samples_leaf": { + "type": "integer", + "minimum": 1 + }, + "l2_regularization": { + "type": "number", + "minimum": 0 + }, + "early_stopping": { + "type": "boolean" + }, + "validation_fraction": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1 + }, + "n_iter_no_change": { + "type": "integer", + "minimum": 1 + }, + "max_iter": { + "type": "integer", + "minimum": 1 + } + } + }, + "logit": { + "type": "object", + "additionalProperties": false, + "required": [ + "n_knots", + "degree", + "knots", + "extrapolation", + "penalty_c", + "solver", + "max_iter" + ], + "properties": { + "n_knots": { + "type": "integer", + "minimum": 2 + }, + "degree": { + "type": "integer", + "minimum": 1 + }, + "knots": { + "enum": [ + "quantile", + "uniform" + ] + }, + "extrapolation": { + "enum": [ + "constant", + "linear", + "continue", + "error" + ] + }, + "penalty_c": { + "type": "number", + "exclusiveMinimum": 0 + }, + "solver": { + "type": "string" + }, + "max_iter": { + "type": "integer", + "minimum": 1 + } + } + }, + "boosted_weight": { + "type": "number", + "minimum": 0, + "maximum": 1 + } + } + }, + "industry": { + "type": "object", + "additionalProperties": false, + "required": [ + "columns", + "cells", + "neighbours", + "rank_columns", + "presence_rank_columns", + "region_scale" + ], + "properties": { + "columns": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "cells": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "neighbours": { + "type": "integer", + "minimum": 1 + }, + "rank_columns": { + "type": "array", + "items": { + "type": "string" + } + }, + "presence_rank_columns": { + "type": "array", + "items": { + "type": "string" + } + }, + "region_scale": { + "type": "number", + "minimum": 0 + } + } + }, + "evidence": { + "type": "object", + "additionalProperties": false, + "required": [ + "folds", + "pay_band_quantiles" + ], + "properties": { + "folds": { + "type": "integer", + "minimum": 2 + }, + "pay_band_quantiles": { + "type": "array", + "minItems": 1, + "items": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1 + } + } + } + } + } + }, { "type": "object", "additionalProperties": false, diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index e5c94cf3b3..5e36020f40 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -1076,6 +1076,27 @@ }, "notes": "Stage-time rules of the company_cars receipt that hold for any population (PolicyEngine/uk-autumn-budget-dashboard-2026#316). It fails on any record the receipt counts against them (a non-finite or negative value; a holder without a list price; an input written for someone without a car; an unknown fuel type; a car that emits CO2 without a figure, or an electric car with one; private fuel on an electric car; contributions above the list price; an electric range on a car outside 1 to 50 g/km; an SPI benefit above its EPB; a tape row's employee pension contribution above its carved pay, which salary_sacrifice would refuse) and on any tape row whose pay plus the car and fuel benefits the engine computes again on the stage's output misses the pay the row brought in (the tape's PAY + EPB + TAXTERM) by more than maximum_pay_identity_error_gbp, rounded up to the penny: the carve-out of the benefits from pay assumes how the engine prices a car, and the engine computes in single precision (María's ruling of 30 October 2026). It is no population fact check, so the synthetic smoke build blocks on it as every licensed build does; how far the calibrated file sits from HMRC's company car tables is not gated (María's ruling of 28 October 2026 on the ISA facts), and no build step measures it yet: comparing the calibrated file with Tables 1, 3A and 4 is a manual step." }, + { + "id": "uk_stage_spi_employment_shell_fit", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "population_fact_check": true, + "parameters": { + "stage": "spi_employment_shell", + "check": "occupation_redraw", + "minimum_log_loss_gain": 0.2, + "calibration_slope_bounds": [ + 0.85, + 1.15 + ], + "maximum_pay_band_share_gap": 0.03, + "maximum_status_group_share_gap": 0.03, + "maximum_blend_log_loss_excess": 0.005 + }, + "notes": "Stage-time check of the spi_employment_shell receipt's held-out evidence (microcosm#1490): five folds dealing whole FRS households, scored on the FRS adults the occupation model trains on. It fails when the evidence was not measured; when the model's out-of-fold log loss is not at least minimum_log_loss_gain below the constant's (the training folds' class shares); when the blend's log loss exceeds its better learner's by more than maximum_blend_log_loss_excess; when the calibration slope (1 when the probabilities spread as much as the outcomes do) falls outside calibration_slope_bounds or the Platt fit fell back to class rates; when the weighted mean gap between predicted and observed occupation shares within the pay bands exceeds maximum_pay_band_share_gap; or when the largest gap within a status group exceeds maximum_status_group_share_gap. The bounds sit wide of the blend measured on FRS 2024-25 coded adults: a log-loss gain of 0.30, a slope of 1.01, a pay-band gap of 0.013, status-group gaps of at most 0.012, and a log loss 0.010 below its better learner. A population fact check: a synthetic smoke build records it without blocking, since a fixture of a few households cannot fit the population's occupation model." + }, { "id": "uk_release_input_coverage", "gate": "release_input_coverage", 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 1e4275e332..d19af9bad1 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 @@ -472,7 +472,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -495,7 +495,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -518,7 +518,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -540,7 +540,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -570,7 +570,7 @@ "uc_is_in_gainful_self_employment" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "The FRS job record's company car answers through frs_spine's carriers (EXPBEN01, EXPBEN03, CARVAL, FUELTYP, CARCON, CARAMT), WAS round-8 company cars' list prices, and HMRC's 2024-25 company car recipients by CO2 band (Table 2A) and fuel (Table 2C), via the vendored facts", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" @@ -599,7 +599,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -619,7 +619,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -641,7 +641,7 @@ "required_mass_change_reason": "High-value home support divides every owner household in the top value stratum of its region into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "Microcosm structural operator (microcosm#1240 fix 1); no publisher input", "survey": "Family Resources Survey 2024-25 and SPI synthetic support, after the WAS wealth draw and the regional property uprating" @@ -662,7 +662,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -686,7 +686,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "6a2ba5e3e43c6d7936416552aadc716729b902dcac24b97093ae8ccf06cf8a8f", @@ -776,7 +776,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -803,7 +803,7 @@ "required_mass_change_reason": "ISA subscriptions per adult from HMRC's ISA tables on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "HMRC Individual Savings Account statistics Tables 9.4, 9.6 and 9.7 to 9.9, the cash ISA limit reduction impact note and Lifetime ISA Table 1a, via the vendored facts; Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "HMRC Annual savings statistics (September 2026 release); Wealth and Assets Survey round 8" @@ -873,7 +873,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "UK Data Service SN 9603 Living Costs and Food Survey 2024-25 (2nd edition) household/person tabs and the vendored Chronicle facts for NEED 2024 mean kWh, DESNZ Energy Trends and QEP average prices paid for calendar 2024, road-fuel outturn (DESNZ, HMRC, ONS Consumer Trends) and road fuel by vehicle type (DESNZ), ONS Consumer Trends household spending by COICOP division, the DfT VEH1103 licensed-car stock, NTS bus use, the NTS private cars (UK Data Service SN 5340, End User Licence; the vehicle and household tabs, survey years 2022-2024) for the zero-emission share by income fifth and the household-paid road-fuel mix, and the DfT and devolved bus finance tables and fares indices.", "survey": "Living Costs and Food Survey 2024-25" @@ -899,7 +899,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -919,7 +919,7 @@ "required_mass_change_reason": "Private-school attendance stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "policyengine-uk attends_private_school (the gov.simulation.private_school_vat attendance rates and factor), evaluated by the pinned engine", "survey": "policyengine-uk private-school attendance imputation, stored at the spine's weights" @@ -942,7 +942,7 @@ "property_finance_costs" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/property-rental-income-statistics", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Property Rental Income Statistics 2026 (tax year 2024-25)" @@ -963,7 +963,7 @@ "required_mass_change_reason": "Annual property purchases imputed on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/uk-stamp-tax-statistics", "survey": "HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected 11 March 2026), Tables 6b, 8a and 8b" @@ -986,7 +986,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "uk/high_value_home_value_knots.json, built by tools/build_uk_high_value_home_stock.py from PolicyEngine/chronicle#343's registrations", "survey": "HM Land Registry Price Paid latest sales uprated with the UK House Price Index, owner-weighted by region (the dense value node's knots, region level)" @@ -1010,7 +1010,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "MHCLG dwellings and the UK House Price Index regional average price averaged over the twelve months of calendar 2024 from the July 2026 full file, the frame's valuation basis, so the engine's annual uprating from 2024 projects the value once (microcosm#1240 fix 5).", "survey": "Public regional property reference" @@ -1038,7 +1038,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -1071,7 +1071,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -1094,7 +1094,7 @@ "student_loan_balance" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "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" @@ -1114,7 +1114,7 @@ "required_mass_change_reason": "Self-employed gross receipts stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "self_employment_income after the SPI income stage; HMRC's published gainers of the raise to GBP 3,000, about 400,000 taxpayers with a lower bill by about GBP 380 on average", "survey": "The self-employed's own profit on the final spine, and HMRC's policy paper on the Budget 2026 trading allowance raise (calibration)" @@ -1136,7 +1136,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -1175,7 +1175,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": "a8af07f3485fc4124a862e08ec1048a577f6290848e8f68a94f7142881a045c1", + "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index c68f2faeb5..07413cbca8 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -2875,6 +2875,105 @@ "stage": "company_cars", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" }, + { + "artifacts": [], + "grain": "person", + "notes": "Runs after company_cars, so the SPI-drawn rows' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region, falling back to the group and then to all adults where a cell holds fewer; so occupation and industry stay a pair that occurs. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", + "operations": [ + { + "evidence": { + "folds": 5, + "pay_band_quantiles": [ + 0.5, + 0.8, + 0.9, + 0.95, + 0.99 + ] + }, + "identity": "person_id", + "industry": { + "cells": [ + "soc2020_major_group", + "status_group" + ], + "columns": [ + "sic_industry_division", + "employment_sector" + ], + "neighbours": 50, + "presence_rank_columns": [ + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "rank_columns": [ + "age" + ], + "region_scale": 0.3 + }, + "kind": "impute_spi_employment_shell", + "occupation": { + "arcsinh_columns": [ + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "arcsinh_scale": 1000, + "boosted": { + "early_stopping": true, + "l2_regularization": 1, + "learning_rate": 0.05, + "max_iter": 500, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "n_iter_no_change": 20, + "validation_fraction": 0.2 + }, + "boosted_weight": 0.5, + "categorical_predictors": [ + "gender", + "region", + "status_group" + ], + "logit": { + "degree": 3, + "extrapolation": "constant", + "knots": "quantile", + "max_iter": 3000, + "n_knots": 6, + "penalty_c": 1, + "solver": "lbfgs" + }, + "predictors": [ + "age", + "gender", + "region", + "status_group", + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "target": "soc2020_major_group" + }, + "rows": "spi_income_recipients_with_occupation_pay_or_profit", + "seed": 0, + "training_rows": "frs_channel_adults_with_occupation_positive_weight" + } + ], + "outputs": [], + "rewrites": [ + "soc2020_major_group", + "sic_industry_division", + "employment_sector" + ], + "source": "Family Resources Survey 2024-25 adults' SOC 2020 major group, SIC 2007 division and sector, redrawn onto the SPI-drawn rows from their own incomes (microcosm#1490).", + "stage": "spi_employment_shell", + "survey": "Family Resources Survey 2024-25" + }, { "stage": "spi_housing_shell", "survey": "Family Resources Survey 2024-25", 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 d31e90995c..5f3082dd48 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -2438,6 +2438,86 @@ stages: - employment_income - uc_is_in_gainful_self_employment notes: 'Writes six of policyengine-uk 2.165.0''s company car inputs (PolicyEngine/uk-autumn-budget-dashboard-2026#316) right after the SPI income stage, so every later stage reads the tape rows'' pay without the car benefits, as the engine''s employment_income excludes them, and salary_sacrifice bounds its sacrifice on that pay (María''s ruling of 31 October 2026). An FRS-channel person keeps the company car frs_spine''s carriers record; a tape row of the SPI channel (person_is_spi_income_recipient) keeps its twin''s only where its drawn EPB is positive, and the channel''s other rows, which keep their twin''s pay, keep its car. Fuel maps from the FRS code (a hybrid is an alternative fuel; a diesel meets RDE2, which every new diesel has since January 2021), and the unknown fuels draw at Table 2C''s shares together: without electricity where the respondent reports private fuel, and with the others'' electric share raised to keep Table 2C''s at the stage''s weights. The list price is drawn within the respondent''s CARVAL band from WAS round-8 company cars'' prices grown by the engine''s CPI index from 2021, the open and unknown bands by fuel class, uniformly from no lower than minimum_scaled_list_price_gbp where a band has fewer than minimum_donor_households WAS households. CO2 is zero for an electric car; the others split between 1 to 50 g/km (hybrids first) and the bands above at Table 2A''s shares among cars that emit CO2, uniformly within each band, and a car at 1 to 50 g/km takes electric_range_miles. Availability, payments for private use and the 2020 registration flag keep the engine''s defaults, which no survey records. A tape row''s pay is the tape''s PAY + EPB + TAXTERM, so the engine''s car and fuel benefits come out of employment_income, capped at EPB within the pay the row''s employee pension contribution leaves (the SPI income stage capped that contribution at the drawn pay, and salary_sacrifice refuses one above the pay that remains): where the two do not fit together the fuel goes first, then the list price is scaled down to fit with its contributions dropped, or the car dropped below minimum_scaled_list_price_gbp (María''s rulings of 30 and 31 October 2026). A scaled price is the room over the car''s appropriate percentage, so the CO2 draw, electric_range_miles and the RDE2 diesel set it, and with it the base the 2030-31 rise acts on. The stage then prices its output again on the engine: on every tape row, pay plus the benefits must equal the pay the row brought in. A carved row''s UC gainful self-employment, which the SPI income stage set on the drawn pay, takes the root''s rule again on the carved pay. No HMRC fact is a calibration target: binding the cells the stage draws to would be circular. No build step reads Tables 1, 3A and 4 after calibration yet: comparing the calibrated file with them is a manual step.' +- stage: spi_employment_shell + survey: Family Resources Survey 2024-25 + source: Family Resources Survey 2024-25 adults' SOC 2020 major group, SIC 2007 division and sector, redrawn onto the SPI-drawn rows from their own incomes (microcosm#1490). + grain: person + artifacts: [] + operations: + - kind: impute_spi_employment_shell + training_rows: frs_channel_adults_with_occupation_positive_weight + rows: spi_income_recipients_with_occupation_pay_or_profit + identity: person_id + seed: 0 + occupation: + target: soc2020_major_group + predictors: + - age + - gender + - region + - status_group + - employment_income + - self_employment_income + - investment_income + - private_pension_income + categorical_predictors: + - gender + - region + - status_group + arcsinh_columns: + - employment_income + - self_employment_income + - investment_income + - private_pension_income + arcsinh_scale: 1000.0 + boosted: + learning_rate: 0.05 + max_leaf_nodes: 15 + min_samples_leaf: 40 + l2_regularization: 1.0 + early_stopping: true + validation_fraction: 0.2 + n_iter_no_change: 20 + max_iter: 500 + logit: + n_knots: 6 + degree: 3 + knots: quantile + extrapolation: constant + penalty_c: 1.0 + solver: lbfgs + max_iter: 3000 + boosted_weight: 0.5 + industry: + columns: + - sic_industry_division + - employment_sector + cells: + - soc2020_major_group + - status_group + neighbours: 50 + rank_columns: + - age + presence_rank_columns: + - employment_income + - self_employment_income + - investment_income + - private_pension_income + region_scale: 0.3 + evidence: + folds: 5 + pay_band_quantiles: + - 0.5 + - 0.8 + - 0.9 + - 0.95 + - 0.99 + outputs: [] + rewrites: + - soc2020_major_group + - sic_industry_division + - employment_sector + notes: 'Runs after company_cars, so the SPI-drawn rows'' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region, falling back to the group and then to all adults where a cell holds fewer; so occupation and industry stay a pair that occurs. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' - stage: spi_housing_shell survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 base households' housing (tenure, dwelling type, bedrooms, council tax, housing costs and the housing-linked benefit reports), imputed onto the SPI support households from their own region, composition and post-SPI incomes. 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 3736a1b09f..aa5085a375 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 @@ -2193,6 +2193,15 @@ def _ledger_compile_parity_required_artifacts( # The company_cars check (dashboard #316): how far SPI-channel # pay plus its carved benefits may miss the tape's total. "maximum_pay_identity_error_gbp", + # The occupation_redraw check (microcosm#1490): the held-out + # log-loss gain over the constant, the calibration slope's + # bounds, the occupation-share gaps within pay bands and status + # groups, and the blend's allowance over its better learner. + "minimum_log_loss_gain", + "calibration_slope_bounds", + "maximum_pay_band_share_gap", + "maximum_status_group_share_gap", + "maximum_blend_log_loss_excess", # #1113 road_fuel_incidence check: the ceiling on the chain's # zero share among flagged fuel-car households. "maximum_flagged_zero_share", 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 249f8c3c2a..7656494931 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 @@ -158,6 +158,7 @@ "uk_stage_isa_subscriptions_invariants", "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", + "uk_stage_spi_employment_shell_fit", # Weight-independent like the BRMA enum below, and its column exists from # frs_relationships onward (#791). "uk_ons_household_type_enum_domain", 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 44babffc2d..6372946355 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -119,6 +119,11 @@ # units without an observed FRS capital answer. _READER_ISOLATION_BOUNDARIES = frozenset( { + # The employment shell rewrites the root person cells + # soc2020_major_group, sic_industry_division and employment_sector after + # the open-surface SPI income stage and the company cars, which would + # otherwise bind them (microcosm#1490). + "spi_employment_shell", # The housing shell rewrites root household cells after the # open-surface SPI income stage and the company cars, which would # otherwise bind them. @@ -380,6 +385,26 @@ "spi_support_channel": None, "spi_income_band_donors": None, "hmrc_spi_income_spine": None, + # Engine-free: the occupation predictors, the drawn-row rule and the channel + # split. The rewritten occupation, industry and sector cells arrive as the + # rewrite's incumbents (microcosm#1490). + "spi_employment_shell": frozenset( + { + ("person", "age"), + ("person", "gender"), + ("person", "employment_status"), + ("person", "employment_income"), + ("person", "self_employment_income"), + ("person", "savings_interest_income"), + ("person", "dividend_income"), + ("person", "private_pension_income"), + ("person", "person_is_spi_income_recipient"), + ("person", "hmrc_spi_pay"), + ("household", "region"), + ("household", "household_support_channel"), + ("household", "household_source_id"), + } + ), # Engine-free: the housing predictors and the channel split. The rewritten # housing and benefit cells arrive as the rewrite's incumbents. "spi_housing_shell": frozenset( @@ -1148,6 +1173,11 @@ def _cells( _Cell("person", "person_is_spi_income_band_carrier", "bool"), ), "hmrc_spi_income_spine": (), # populated below from typed groups + "spi_employment_shell": ( + _Cell("person", "soc2020_major_group", "string"), + _Cell("person", "sic_industry_division", "int64"), + _Cell("person", "employment_sector", "string"), + ), "spi_housing_shell": ( *_cells( "household", 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 12a5e55f7b..7989108665 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 @@ -26,6 +26,9 @@ import numpy as np import pandas as pd +from microcosm.fit import categorical as fit_categorical +from microcosm.fit import donors as fit_donors +from microcosm.fit import held_out as fit_held_out from microcosm.frame import Frame, MassChangeRecord, WeightKind from microcosm.frame.adapters import policyengine_uk as uk_engine_adapter from microcosm.graph import ( @@ -62,6 +65,7 @@ household_lineage, ledger_fact_vendoring, legacy_closure_take_up, + occupation_constants, property_localisation, receipt_counts, rowwise_geography, @@ -116,6 +120,7 @@ "spi_support_channel": "spi_spine", "spi_income_band_donors": "spi_band_donors", "hmrc_spi_income_spine": "spi_spine", + "spi_employment_shell": "spi_employment_shell", "spi_housing_shell": "spi_housing_shell", "uc_reporter_redraw": "uc_reporter_redraw", "spi_benefit_coherence": "spi_benefit_coherence", @@ -264,6 +269,18 @@ # helper, reads each household's clone path, and measures its flags for # the stage-time signal gate by the shared disclosure rules (microcosm#1095). "childcare_copy_take_up": (frs_take_up, household_lineage, receipt_counts), + # The employment shell fits, scores and draws through microcosm.fit's + # categorical classifier, held-out scores and keyed donors, reads the + # shared occupation codes, and counts its receipt's support by the shared + # disclosure rules (microcosm#1490). + "spi_employment_shell": ( + fit_categorical, + fit_donors, + fit_held_out, + occupation_constants, + receipt_counts, + stochastic_assignment, + ), } _COMPUTE = Capabilities( @@ -606,6 +623,7 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: from .salary_sacrifice import UKSalarySacrificeStageTransform from .spi_band_donors import UKSPIIncomeBandDonorStageTransform from .spi_benefit_coherence import UKSPIBenefitCoherenceStageTransform + from .spi_employment_shell import UKSPIEmploymentShellStageTransform from .spi_housing_shell import UKSPIHousingShellStageTransform from .spi_spine import ( UKFRSHMRCSpineLeavesStageTransform, @@ -807,6 +825,9 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: donor_table=spi_donor, source_targets=income_targets, ), + "spi_employment_shell": UKSPIEmploymentShellStageTransform( + stage=stages["spi_employment_shell"], boosted_max_iter=qrf_estimators + ), "spi_housing_shell": UKSPIHousingShellStageTransform( stage=stages["spi_housing_shell"], n_estimators=qrf_estimators ), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py index 8254fa56ff..8bef7fd60b 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py @@ -1,10 +1,12 @@ -"""UK occupation codes: the engine's SOC 2020 groups and the codings the build reads.""" +"""UK occupation and industry codes: the engine's SOC 2020 groups and the codings the build reads.""" from __future__ import annotations from collections.abc import Mapping from types import MappingProxyType +import numpy as np + #: The engine's ``soc2020_major_group`` member for a person with no occupation #: recorded: a child, an adult who has never worked, or an unknown code. UK_SOC2020_NO_OCCUPATION = "NONE" @@ -36,8 +38,70 @@ } ) +#: The employment-status group an occupation draw conditions on, by the +#: engine's ``employment_status`` member. CHILD has none: a child holds no +#: occupation. +UK_OCCUPATION_STATUS_GROUP: Mapping[str, str] = MappingProxyType( + { + "FT_EMPLOYED": "EMPLOYEE", + "PT_EMPLOYED": "EMPLOYEE", + "FT_SELF_EMPLOYED": "SELF_EMPLOYED", + "PT_SELF_EMPLOYED": "SELF_EMPLOYED", + "RETIRED": "RETIRED", + "UNEMPLOYED": "OTHER", + "STUDENT": "OTHER", + "CARER": "OTHER", + "LONG_TERM_DISABLED": "OTHER", + "SHORT_TERM_DISABLED": "OTHER", + "OTHER_INACTIVE": "OTHER", + } +) + +#: The SIC 2007 sections A-U by the first and last of their two-digit +#: divisions (ONS UK SIC 2007). Divisions 4, 34 and the other gaps exist in +#: no section. +UK_SIC2007_SECTION_DIVISIONS: Mapping[str, tuple[int, int]] = MappingProxyType( + { + "A": (1, 3), + "B": (5, 9), + "C": (10, 33), + "D": (35, 35), + "E": (36, 39), + "F": (41, 43), + "G": (45, 47), + "H": (49, 53), + "I": (55, 56), + "J": (58, 63), + "K": (64, 66), + "L": (68, 68), + "M": (69, 75), + "N": (77, 82), + "O": (84, 84), + "P": (85, 85), + "Q": (86, 88), + "R": (90, 93), + "S": (94, 96), + "T": (97, 98), + "U": (99, 99), + } +) + + +def uk_sic2007_sections(divisions) -> np.ndarray: + """Each two-digit SIC 2007 division's section letter; "" outside every section.""" + + values = np.asarray(divisions, dtype=np.int64) + out = np.full(values.shape, "", dtype=object) + for section, (first, last) in UK_SIC2007_SECTION_DIVISIONS.items(): + out[(values >= first) & (values <= last)] = section + return out + + __all__ = [ "UK_FRS_SOC2020_MAJOR_GROUP", + "UK_OCCUPATION_STATUS_GROUP", + "UK_SIC2007_SECTION_DIVISIONS", "UK_SOC2020_MAJOR_GROUPS", "UK_SOC2020_NO_OCCUPATION", + "uk_sic2007_sections", ] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py new file mode 100644 index 0000000000..267b7ceb02 --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py @@ -0,0 +1,685 @@ +"""Redraw the SPI-drawn rows' occupation from their own incomes, with a coherent industry. + +The SPI support channel and the income band donors are whole copies of FRS +households, and ``hmrc_spi_income_spine`` then draws their claimants' and +partners' incomes from the SPI tape. A drawn row keeps its FRS twin's SOC 2020 +major group, industry and sector, all chosen with the twin's pay, not the +incomes it drew; held out on the FRS, the twin's group misses the occupation +mix of people at the drawn pay by 0.15 to 0.38 (total variation) in every paid +band. This stage is the person counterpart of ``spi_housing_shell``: it trains +on the FRS rows' adults with an occupation and draws each drawn row's major +group from its age, sex, region, employment-status group and incomes, then +copies an industry division and sector pair from an FRS adult with the drawn +group, the same status group and the nearest age and incomes, so occupation and +industry stay a pair that occurs. + +The model is ``microcosm.fit``'s country-agnostic categorical classifier, the +equal mixture of a regularised boosted classifier and a spline logit; the held- +out evidence and the donor choice are its held-out scores and keyed nearest +donors. Every draw reads uniforms keyed on ``person_id``, so adding or +reordering rows never moves a draw. FRS rows, undrawn copies, and drawn rows +whose twin had no occupation and who drew no pay or profit are byte-unchanged. +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence +from dataclasses import dataclass, field +from typing import Any + +import numpy as np +import pandas as pd + +from microcosm.build.stochastic_assignment import ( + integer_record_keys, + stable_identity_uniforms, +) +from microcosm.build.uk_runtime.occupation_constants import ( + UK_OCCUPATION_STATUS_GROUP, + UK_SOC2020_NO_OCCUPATION, + uk_sic2007_sections, +) +from microcosm.build.uk_runtime.receipt_counts import ( + distinct_count, + rounded_count, + small_cell_share, + source_household_ids, + support_band, +) +from microcosm.fit import ( + BoostedClassifierSettings, + CategoricalClassifier, + SplineLogitSettings, + can_deal_folds, + categorical_scores, + donor_distance_features, + keyed_nearest_donors, + out_of_fold_proba, + stratified_folds, +) + +__all__ = [ + "UK_SPI_EMPLOYMENT_SHELL_OPERATION", + "UK_SPI_EMPLOYMENT_SHELL_REWRITES", + "UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME", + "UKSPIEmploymentShellStageTransform", + "drawn_rows", + "impute_spi_employment_shell", + "occupation_model", +] + +UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME = "spi_employment_shell" +FRS_CHANNEL = "frs" +OCCUPATION_COLUMN = "soc2020_major_group" +INDUSTRY_COLUMNS = ("sic_industry_division", "employment_sector") +UK_SPI_EMPLOYMENT_SHELL_REWRITES: tuple[str, ...] = ( + OCCUPATION_COLUMN, + *INDUSTRY_COLUMNS, +) +STATUS_GROUP = "status_group" +#: Investment income is savings interest plus dividends, as the SPI draws them. +INVESTMENT_COMPONENTS = ("savings_interest_income", "dividend_income") +INCOME_COLUMNS = ( + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income", +) +OCCUPATION_PREDICTORS = ("age", "gender", "region", STATUS_GROUP, *INCOME_COLUMNS) +CATEGORICAL_PREDICTORS = ("gender", "region", STATUS_GROUP) +#: The SPI tape's own PAY: ``employment_income`` can be termination pay or +#: benefits alone, which says nothing of an occupation. +SPI_PAY_COLUMN = "hmrc_spi_pay" +PAY_BANDS = ( + "no_pay", + "below_p50", + "p50_p80", + "p80_p90", + "p90_p95", + "p95_p99", + "top_1pc", +) +_ADULT_AGE = 16 +_PUBLIC_SECTOR = "PUBLIC" + +#: The manifest's operation, mirrored here and checked at stage time. +UK_SPI_EMPLOYMENT_SHELL_OPERATION: dict[str, Any] = { + "training_rows": "frs_channel_adults_with_occupation_positive_weight", + "rows": "spi_income_recipients_with_occupation_pay_or_profit", + "identity": "person_id", + "seed": 0, + "occupation": { + "target": OCCUPATION_COLUMN, + "predictors": list(OCCUPATION_PREDICTORS), + "categorical_predictors": list(CATEGORICAL_PREDICTORS), + "arcsinh_columns": list(INCOME_COLUMNS), + "arcsinh_scale": 1000.0, + "boosted": { + "learning_rate": 0.05, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "l2_regularization": 1.0, + "early_stopping": True, + "validation_fraction": 0.2, + "n_iter_no_change": 20, + "max_iter": 500, + }, + "logit": { + "n_knots": 6, + "degree": 3, + "knots": "quantile", + "extrapolation": "constant", + "penalty_c": 1.0, + "solver": "lbfgs", + "max_iter": 3000, + }, + "boosted_weight": 0.5, + }, + "industry": { + "columns": list(INDUSTRY_COLUMNS), + "cells": [OCCUPATION_COLUMN, STATUS_GROUP], + "neighbours": 50, + "rank_columns": ["age"], + "presence_rank_columns": list(INCOME_COLUMNS), + "region_scale": 0.3, + }, + "evidence": {"folds": 5, "pay_band_quantiles": [0.5, 0.8, 0.9, 0.95, 0.99]}, +} + + +def _plain(value: object) -> object: + """A declaration as plain dicts and lists, for an exact comparison.""" + if isinstance(value, Mapping): + return {str(key): _plain(item) for key, item in value.items()} + if isinstance(value, list | tuple): + return [_plain(item) for item in value] + return value + + +def drawn_rows(person: pd.DataFrame) -> np.ndarray: + """The rows the stage redraws: SPI income recipients whose twin had an + occupation, or who drew pay or a profit of their own.""" + recipient = person["person_is_spi_income_recipient"].astype(bool).to_numpy() + coded = person[OCCUPATION_COLUMN].astype(str).to_numpy() != UK_SOC2020_NO_OCCUPATION + works = (person[SPI_PAY_COLUMN].to_numpy(dtype=np.float64) > 0) | ( + person["self_employment_income"].to_numpy(dtype=np.float64) > 0 + ) + return recipient & (coded | works) + + +def occupation_model( + operation: Mapping[str, Any], *, boosted_max_iter: int | None = None +) -> CategoricalClassifier: + """The declared classifier. + + ``boosted_max_iter`` caps the boosted learner on a small fixture, and turns + its early stopping off there: the validation split early stopping holds out + is stratified, and a fixture of a few households has classes too thin to + split. + """ + occupation = operation["occupation"] + boosted = dict(occupation["boosted"]) + if boosted_max_iter is not None: + boosted["max_iter"] = int(boosted_max_iter) + boosted["early_stopping"] = False + return CategoricalClassifier( + boosted_weight=float(occupation["boosted_weight"]), + boosted=BoostedClassifierSettings(**boosted), + logit=SplineLogitSettings(**dict(occupation["logit"])), + categorical_predictors=tuple(occupation["categorical_predictors"]), + arcsinh_scales={ + column: float(occupation["arcsinh_scale"]) + for column in occupation["arcsinh_columns"] + }, + seed=int(operation["seed"]), + ) + + +def _pay_bands( + pay: np.ndarray, weights: np.ndarray, quantiles: Sequence[float] +) -> np.ndarray: + """No pay, then bands at the weighted quantiles of positive pay.""" + band = np.zeros(len(pay), dtype=np.int64) + positive = pay > 0 + if positive.any(): + order = np.argsort(pay[positive], kind="stable") + cumulative = np.cumsum(weights[positive][order]) + cuts = np.interp(quantiles, cumulative / cumulative[-1], pay[positive][order]) + band[positive] = np.digitize(pay[positive], cuts) + 1 + return band + + +def _person_table(person: pd.DataFrame, household: pd.DataFrame) -> pd.DataFrame: + """The predictors, target, keys and channel of every person.""" + households = household.set_index("household_id") + by_person = person["person_household_id"].to_numpy() + table = pd.DataFrame( + { + "person_id": person["person_id"].to_numpy(), + "household_id": by_person, + "age": person["age"].to_numpy(dtype=np.float64), + "gender": person["gender"].astype(str).to_numpy(), + "region": households["region"].astype(str).reindex(by_person).to_numpy(), + STATUS_GROUP: person["employment_status"] + .astype(str) + .map(UK_OCCUPATION_STATUS_GROUP) + .to_numpy(dtype=object), + "employment_income": person["employment_income"].to_numpy(dtype=np.float64), + "self_employment_income": person["self_employment_income"].to_numpy( + dtype=np.float64 + ), + "investment_income": sum( + person[column].to_numpy(dtype=np.float64) + for column in INVESTMENT_COMPONENTS + ), + "private_pension_income": person["private_pension_income"].to_numpy( + dtype=np.float64 + ), + OCCUPATION_COLUMN: person[OCCUPATION_COLUMN].astype(str).to_numpy(), + "channel": households["household_support_channel"] + .astype(str) + .reindex(by_person) + .to_numpy(), + }, + index=person.index, + ) + return table + + +def _level_gaps( + levels: Mapping[object, Mapping[str, float]], + names: Sequence[str] | None, + support: Mapping[object, int], +) -> tuple[dict[str, object], float, float]: + """Banded per-level share gaps, and their weighted mean and maximum.""" + out: dict[str, object] = {} + total = weighted = largest = 0.0 + for level, values in levels.items(): + name = names[int(level)] if names is not None else str(level) + households = int(support.get(level, 0)) + out[name] = { + "support": support_band(households), + "share_gap": small_cell_share(float(values["share_gap"]), households), + } + total += float(values["weight"]) + weighted += float(values["weight"]) * float(values["share_gap"]) + largest = max(largest, float(values["share_gap"])) + return out, (weighted / total if total else 0.0), largest + + +def _held_out_evidence( + model: CategoricalClassifier, + train: pd.DataFrame, + weights: np.ndarray, + sources: np.ndarray, + folds: np.ndarray, + quantiles: Sequence[float], +) -> dict[str, object]: + """Out-of-fold scores of the model, each learner and the constant.""" + predictors = list(OCCUPATION_PREDICTORS) + out = out_of_fold_proba( + model, train, predictors, OCCUPATION_COLUMN, weights=weights, folds=folds + ) + labels = train[OCCUPATION_COLUMN].to_numpy() + bands = _pay_bands(train["employment_income"].to_numpy(), weights, quantiles) + status = train[STATUS_GROUP].to_numpy() + scores = { + name: categorical_scores( + out[name], + labels, + out["classes"], + weights, + strata={"pay_band": bands, "status_group": status}, + ) + for name in ("model", "boosted", "spline_logit", "marginal") + if name in out + } + model_scores = scores["model"] + band_support = { + band: distinct_count(sources, bands == band) for band in np.unique(bands) + } + status_support = { + group: distinct_count(sources, status == group) for group in np.unique(status) + } + pay, pay_mean, _ = _level_gaps( + model_scores["strata"]["pay_band"], PAY_BANDS, band_support + ) + groups, _, status_max = _level_gaps( + model_scores["strata"]["status_group"], None, status_support + ) + return { + "status": "measured", + "folds": int(len(np.unique(folds))), + "grouping": "household", + "log_loss": {name: float(value["log_loss"]) for name, value in scores.items()}, + "calibration_slope": model_scores["calibration_slope"], + "calibration_outcome": model_scores["calibration_outcome"], + "share_gap": float(model_scores["share_gap"]), + "pay_band_share_gap_mean": float(pay_mean), + "pay_bands": pay, + "status_group_share_gap_max": float(status_max), + "status_groups": groups, + } + + +def _copy_cells(groups: np.ndarray, status: np.ndarray) -> list[np.ndarray]: + """The donor cells finest first: group and status, group, everyone.""" + return [ + np.asarray( + [f"{g}|{s}" for g, s in zip(groups, status, strict=True)], dtype=object + ), + np.asarray(groups, dtype=object), + np.zeros(len(groups), dtype=object), + ] + + +def _copy_donors( + recipients: pd.DataFrame, + donors: pd.DataFrame, + recipient_groups: np.ndarray, + donor_weights: np.ndarray, + uniforms: np.ndarray, + industry: Mapping[str, Any], +) -> tuple[np.ndarray, np.ndarray]: + r, d = donor_distance_features( + recipients, + donors, + rank_columns=list(industry["rank_columns"]), + presence_rank_columns=list(industry["presence_rank_columns"]), + scaled_categoricals={"region": float(industry["region_scale"])}, + ) + return keyed_nearest_donors( + r, + d, + recipient_cells=_copy_cells( + recipient_groups, recipients[STATUS_GROUP].to_numpy() + ), + donor_cells=_copy_cells( + donors[OCCUPATION_COLUMN].to_numpy(), donors[STATUS_GROUP].to_numpy() + ), + donor_weights=donor_weights, + uniforms=uniforms, + k=int(industry["neighbours"]), + ) + + +def _held_out_industry( + train: pd.DataFrame, + industry_values: pd.DataFrame, + weights: np.ndarray, + folds: np.ndarray, + industry: Mapping[str, Any], + seed: int, +) -> dict[str, float]: + """Copy each fold's pairs from the other folds, given the adults' own groups. + + The gaps are the weighted mean, over major groups, of the total variation + between the copied and observed SIC section shares, and of the absolute + public-sector share difference. + """ + copied = np.full(len(train), -1, dtype=np.int64) + keys = train["person_id"].to_numpy() + for fold in np.unique(folds): + test, rest = folds == fold, folds != fold + positions, _ = _copy_donors( + train.loc[test], + train.loc[rest], + train.loc[test, OCCUPATION_COLUMN].to_numpy(), + weights[rest], + stable_identity_uniforms( + keys[test], + seed=seed, + salt=f"{UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME}:held_out_industry", + ), + industry, + ) + copied[test] = np.flatnonzero(rest)[positions] + section = uk_sic2007_sections(industry_values["sic_industry_division"].to_numpy()) + public = ( + industry_values["employment_sector"].astype(str).to_numpy() == _PUBLIC_SECTOR + ) + groups = train[OCCUPATION_COLUMN].to_numpy() + total = section_gap = public_gap = 0.0 + for group in np.unique(groups): + rows = groups == group + w = weights[rows] + observed = pd.Series(w).groupby(section[rows]).sum() / w.sum() + drawn = pd.Series(w).groupby(section[copied[rows]]).sum() / w.sum() + levels = observed.index.union(drawn.index) + gap = ( + 0.5 + * ( + observed.reindex(levels, fill_value=0) + - drawn.reindex(levels, fill_value=0) + ) + .abs() + .sum() + ) + section_gap += w.sum() * float(gap) + public_gap += w.sum() * abs( + float(w @ public[rows] - w @ public[copied[rows]]) / w.sum() + ) + total += w.sum() + return { + "section_share_gap_within_group": section_gap / total, + "public_sector_share_gap_within_group": public_gap / total, + } + + +def _weighted_shares( + values: np.ndarray, weights: np.ndarray, sources: np.ndarray +) -> dict[str, object]: + out: dict[str, object] = {} + total = weights.sum() + for value in np.unique(values): + rows = values == value + out[str(value)] = small_cell_share( + float(weights[rows].sum() / total), distinct_count(sources, rows) + ) + return out + + +def impute_spi_employment_shell( + person: pd.DataFrame, + household: pd.DataFrame, + household_weights: np.ndarray, + *, + operation: Mapping[str, Any] = UK_SPI_EMPLOYMENT_SHELL_OPERATION, + boosted_max_iter: int | None = None, +) -> tuple[pd.DataFrame, dict[str, Any]]: + """Redraw the drawn SPI rows' occupation, industry and sector; FRS rows untouched.""" + + stage = UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME + table = _person_table(person, household) + weight_by_household = pd.Series( + np.asarray(household_weights, dtype=np.float64), + index=household["household_id"].to_numpy(), + ) + weights = weight_by_household.reindex(table["household_id"]).to_numpy() + source_by_household = pd.Series( + source_household_ids(household, stage=stage), + index=household["household_id"].to_numpy(), + ) + sources = source_by_household.reindex(table["household_id"]).to_numpy() + coded = table[OCCUPATION_COLUMN].to_numpy() != UK_SOC2020_NO_OCCUPATION + training = ( + (table["channel"].to_numpy() == FRS_CHANNEL) + & (weights > 0) + & (table["age"].to_numpy() >= _ADULT_AGE) + & coded + ) + recipient = person["person_is_spi_income_recipient"].astype(bool).to_numpy() + drawn = drawn_rows(person) + if (recipient & (table["channel"].to_numpy() == FRS_CHANNEL)).any(): + raise ValueError( + f"{stage}: an FRS-channel row is marked an SPI income recipient." + ) + unmapped = (training | drawn) & pd.isna(table[STATUS_GROUP]).to_numpy() + if unmapped.any(): + statuses = sorted(set(person.loc[unmapped, "employment_status"].astype(str))) + raise ValueError( + f"{stage}: rows to train on or draw for hold employment statuses " + f"{statuses} that have no occupation status group." + ) + if not training.any(): + raise ValueError(f"{stage} needs FRS adults with an occupation to train on.") + + # The training rows in person_id order, so neither the fit (the early + # stopping split, the folds) nor the donor ties depend on how the frame + # orders its rows. + train_rows = np.flatnonzero(training) + train_rows = train_rows[ + np.argsort(table["person_id"].to_numpy()[train_rows], kind="stable") + ] + train = table.iloc[train_rows].reset_index(drop=True) + train_weights = weights[train_rows] + train_sources = sources[train_rows] + model = occupation_model(operation, boosted_max_iter=boosted_max_iter) + seed = int(operation["seed"]) + evidence_settings = operation["evidence"] + fold_count = int(evidence_settings["folds"]) + labels = train[OCCUPATION_COLUMN].to_numpy() + if can_deal_folds(labels, fold_count, groups=train["household_id"].to_numpy()): + folds = stratified_folds( + labels, + fold_count, + np.random.default_rng(np.random.SeedSequence(seed)), + groups=train["household_id"].to_numpy(), + ) + held_out = _held_out_evidence( + model, + train, + train_weights, + train_sources, + folds, + list(evidence_settings["pay_band_quantiles"]), + ) + industry_held_out: dict[str, object] = _held_out_industry( + train, + person.iloc[train_rows][list(INDUSTRY_COLUMNS)].reset_index(drop=True), + train_weights, + folds, + operation["industry"], + seed, + ) + else: + held_out = { + "status": "not_measured", + "reason": "a major group has fewer training households than folds", + "log_loss": None, + "calibration_slope": None, + } + industry_held_out = {"status": "not_measured"} + + fitted = model.fit( + train, list(OCCUPATION_PREDICTORS), [OCCUPATION_COLUMN], weights=train_weights + ) + person_out = person.copy() + recipients = table.loc[drawn].reset_index(drop=True) + keys = integer_record_keys( + recipients["person_id"].to_numpy(), label=f"{stage} person_id" + ) + new_groups = np.asarray([], dtype=object) + copy_levels = np.asarray([], dtype=np.int64) + if len(recipients): + new_groups = fitted.predict_from_uniforms( + recipients, + stable_identity_uniforms( + keys, seed=seed, salt=f"{stage}:{OCCUPATION_COLUMN}" + ), + )[OCCUPATION_COLUMN].to_numpy() + donor_positions, copy_levels = _copy_donors( + recipients, + train, + new_groups, + train_weights, + stable_identity_uniforms(keys, seed=seed, salt=f"{stage}:industry"), + operation["industry"], + ) + donor_rows = train_rows[donor_positions] + person_out.loc[drawn, OCCUPATION_COLUMN] = new_groups + for column in INDUSTRY_COLUMNS: + person_out.loc[drawn, column] = person[column].to_numpy()[donor_rows] + + drawn_weights = weights[drawn] + receipt: dict[str, Any] = { + "training": { + "people": rounded_count(int(training.sum())), + "source_households": rounded_count(distinct_count(sources, training)), + }, + "drawn": { + "people": rounded_count(int(drawn.sum())), + "twin_had_an_occupation": rounded_count(int((drawn & coded).sum())), + "newly_coded": rounded_count(int((drawn & ~coded).sum())), + "kept_no_occupation": rounded_count(int((recipient & ~drawn).sum())), + }, + "fit": fitted.diagnostics, + "held_out": held_out, + "category_shares": { + "training": _weighted_shares(labels, train_weights, train_sources), + "drawn": ( + _weighted_shares(new_groups, drawn_weights, sources[drawn]) + if len(recipients) + else {} + ), + }, + "industry_copy": { + "neighbours": int(operation["industry"]["neighbours"]), + "levels": { + name: rounded_count(int((copy_levels == level).sum())) + for level, name in enumerate(("group_and_status", "group", "everyone")) + }, + "held_out": industry_held_out, + }, + } + return person_out, receipt + + +def _assert_stage_parameters(stage) -> None: + if stage.stage != UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME: + raise ValueError( + f"Employment shell received stage {stage.stage!r}, expected " + f"{UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME!r}." + ) + kinds = [operation.kind for operation in stage.operations] + if kinds != ["impute_spi_employment_shell"]: + raise ValueError( + "spi_employment_shell operations drifted: expected " + f"['impute_spi_employment_shell'], got {kinds}." + ) + actual = _plain(dict(stage.operations[0].parameters)) + if actual != _plain(UK_SPI_EMPLOYMENT_SHELL_OPERATION): + raise ValueError( + "spi_employment_shell parameters drifted: expected " + f"{UK_SPI_EMPLOYMENT_SHELL_OPERATION}, got {actual}." + ) + if stage.outputs != () or tuple(stage.rewrites) != UK_SPI_EMPLOYMENT_SHELL_REWRITES: + raise ValueError( + "spi_employment_shell must declare no new outputs and exactly the " + f"rewrites {list(UK_SPI_EMPLOYMENT_SHELL_REWRITES)}." + ) + + +def _assert_invariants( + person_in: pd.DataFrame, person_out: pd.DataFrame, drawn: np.ndarray +) -> None: + """Only drawn rows change, and only in the rewritten columns.""" + untouched = [ + c for c in person_in.columns if c not in UK_SPI_EMPLOYMENT_SHELL_REWRITES + ] + if not person_in[untouched].equals(person_out[untouched]): + raise ValueError("Employment shell modified a column it does not rewrite.") + if not person_in.loc[~drawn].equals(person_out.loc[~drawn]): + raise ValueError("Employment shell modified a row it does not draw.") + groups = person_out.loc[drawn, OCCUPATION_COLUMN].astype(str) + if (groups == UK_SOC2020_NO_OCCUPATION).any(): + raise ValueError("Employment shell left a drawn row with no occupation.") + + +@dataclass +class UKSPIEmploymentShellStageTransform: + """Whole-stage callable: redraw the drawn SPI rows' occupation and industry.""" + + stage: Any + boosted_max_iter: int | None = None + last_receipt: dict[str, Any] | None = field(default=None, init=False) + + def __call__(self, frame): + from microcosm.build.uk_runtime.national_frame import ( + uk_household_weight_kind, + uk_national_frame, + uk_time_period, + validate_uk_national_frame, + ) + + _assert_stage_parameters(self.stage) + validate_uk_national_frame(frame) + person = frame.table("person") + person_out, receipt = impute_spi_employment_shell( + person, + frame.table("household"), + np.asarray(frame.weights_for("household").values, dtype=float), + boosted_max_iter=self.boosted_max_iter, + ) + _assert_invariants(person, person_out, drawn_rows(person)) + result = uk_national_frame( + person=person_out, + benunit=frame.table("benunit").copy(), + household=frame.table("household").copy(), + time_period=uk_time_period(frame), + weight_kind=uk_household_weight_kind(frame), + household_weights=frame.weights_for("household").values, + mass_log=frame.mass_log, + ) + validate_uk_national_frame(result) + self.last_receipt = {"stage": UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME, **receipt} + return result + + @staticmethod + def output_columns() -> tuple[str, ...]: + return () + + def checkpoint_metadata(self) -> dict[str, object]: + if self.last_receipt is None: + raise RuntimeError("checkpoint metadata requires a completed stage run.") + return {"evidence": self.last_receipt} diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py index bd4ab37284..0e8f462884 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py @@ -195,6 +195,9 @@ UK_SPI_PUBLIC_USE_TAPE_KEY, uk_spi_public_use_tape_marker, ) +from microcosm.build.uk_runtime.spi_employment_shell import ( + UKSPIEmploymentShellStageTransform, +) from microcosm.build.uk_runtime.spi_housing_shell import ( UKSPIHousingShellStageTransform, ) @@ -844,7 +847,10 @@ def _declared_seeds(stages) -> dict[str, dict[str, int]]: # Identity-keyed draws: the seed is declared under the # salt it is hashed with (microcosm#1063). stage_seeds[str(operation.parameters["salt"])] = seed - elif operation.kind == "impute_spi_housing_shell": + elif operation.kind in ( + "impute_spi_employment_shell", + "impute_spi_housing_shell", + ): stage_seeds[stage.stage] = seed elif operation.kind == "price_domestic_energy": stage_seeds["gas_disconnection"] = seed @@ -1839,6 +1845,10 @@ def prepare_uk_spine_execution( ) ) implementations["hmrc_spi_income_spine"] = hmrc_spine_transform + if "spi_employment_shell" in stage_names: + implementations["spi_employment_shell"] = UKSPIEmploymentShellStageTransform( + stage=stages_by_name["spi_employment_shell"] + ) if "spi_housing_shell" in stage_names: implementations["spi_housing_shell"] = UKSPIHousingShellStageTransform( stage=stages_by_name["spi_housing_shell"] 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 86af8dd57d..7316a766d1 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 @@ -124,6 +124,8 @@ def uk_stage_health_gate( return _was_lisa_anchor_gate(stage, evidence, parameters) if check == "company_cars": return _company_cars_gate(stage, evidence, parameters) + if check == "occupation_redraw": + return _occupation_redraw_gate(stage, evidence, parameters) return GateResult( name="stage_health", passed=False, @@ -5296,3 +5298,109 @@ def _company_cars_gate( failures=tuple(failures), details={"stage": stage, "check": check, "holders": dict(holders)}, ) + + +def _occupation_redraw_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """The occupation redraw's held-out evidence (microcosm#1490). + + Fails when the evidence was not measured; when the model's out-of-fold log + loss is not ``minimum_log_loss_gain`` below the constant's; when the blend + loses more than ``maximum_blend_log_loss_excess`` to its better learner; + when the calibration slope leaves ``calibration_slope_bounds`` or the Platt + fit fell back to class rates; or when the occupation shares miss the + observed ones by more than ``maximum_pay_band_share_gap`` (weighted mean + over the pay bands) or ``maximum_status_group_share_gap`` (largest status + group). + """ + + check = "occupation_redraw" + minimum_gain = _finite_number( + parameters["minimum_log_loss_gain"], label=f"{stage}.minimum_log_loss_gain" + ) + low, high = ( + _finite_number(bound, label=f"{stage}.calibration_slope_bounds") + for bound in parameters["calibration_slope_bounds"] + ) + maximum_pay = _finite_number( + parameters["maximum_pay_band_share_gap"], + label=f"{stage}.maximum_pay_band_share_gap", + ) + maximum_status = _finite_number( + parameters["maximum_status_group_share_gap"], + label=f"{stage}.maximum_status_group_share_gap", + ) + maximum_excess = _finite_number( + parameters["maximum_blend_log_loss_excess"], + label=f"{stage}.maximum_blend_log_loss_excess", + ) + held_out = _mapping(evidence.get("held_out"), label=f"{stage}.held_out") + details: dict[str, object] = {"stage": stage, "check": check} + if held_out.get("status") != "measured": + return GateResult( + name="stage_health", + passed=False, + failures=( + f"{stage}: the held-out evidence was not measured " + f"({held_out.get('reason')}).", + ), + details=details, + ) + failures: list[str] = [] + losses = _mapping(held_out.get("log_loss"), label=f"{stage}.held_out.log_loss") + model = _finite_number(losses.get("model"), label=f"{stage}.log_loss.model") + constant = _finite_number( + losses.get("marginal"), label=f"{stage}.log_loss.marginal" + ) + if constant - model < minimum_gain: + failures.append( + f"{stage}: the model's log loss ({model:.4f}) is less than " + f"{minimum_gain} below the constant's ({constant:.4f})." + ) + learners = { + name: _finite_number(losses[name], label=f"{stage}.log_loss.{name}") + for name in ("boosted", "spline_logit") + if name in losses + } + if len(learners) == 2 and model > min(learners.values()) + maximum_excess: + failures.append( + f"{stage}: the blend's log loss ({model:.4f}) exceeds its better " + f"learner's ({min(learners.values()):.4f}) by more than {maximum_excess}." + ) + slope = held_out.get("calibration_slope") + if slope is None or held_out.get("calibration_outcome") != "cross_fitted": + failures.append(f"{stage}: the calibration slope could not be fitted.") + else: + value = _finite_number(slope, label=f"{stage}.calibration_slope") + if not low <= value <= high: + failures.append( + f"{stage}: the calibration slope {value:.3f} is outside [{low}, {high}]." + ) + pay_gap = _finite_number( + held_out.get("pay_band_share_gap_mean"), + label=f"{stage}.pay_band_share_gap_mean", + ) + if pay_gap > maximum_pay: + failures.append( + f"{stage}: occupation shares miss within the pay bands by {pay_gap:.4f} " + f"on average, above {maximum_pay}." + ) + status_gap = _finite_number( + held_out.get("status_group_share_gap_max"), + label=f"{stage}.status_group_share_gap_max", + ) + if status_gap > maximum_status: + failures.append( + f"{stage}: occupation shares miss within a status group by {status_gap:.4f}, " + f"above {maximum_status}." + ) + details.update({"log_loss": dict(losses), "calibration_slope": slope}) + return GateResult( + name="stage_health", + passed=not failures, + failures=tuple(failures), + details=details, + ) diff --git a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py index aaabbd1bfa..e01fe9e92a 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py @@ -1199,7 +1199,7 @@ def test_uk_source_manifest_contains_only_canonical_spine_stages(self) -> None: # frs_annual_income_spells after frs_hmrc_spine_leaves; microcosm#1428 # trading_allowance_receipts last; company_cars right after # hmrc_spi_income_spine (PolicyEngine/uk-autumn-budget-dashboard-2026#316). - assert len(spec.sources.stages) == 52 + assert len(spec.sources.stages) == 53 assert not {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.intersection( stage.stage for stage in spec.sources.stages ) @@ -1641,6 +1641,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_stage_isa_subscriptions_invariants", "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", + "uk_stage_spi_employment_shell_fit", "uk_release_input_coverage", "uk_degenerate_release_surface", "uk_zero_weight_strata", @@ -1782,6 +1783,7 @@ def test_strict_absent_evidence_entries_are_declared(self, manifest) -> None: "uk_stage_isa_subscriptions_invariants", "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", + "uk_stage_spi_employment_shell_fit", "uk_weights_audit", # The #970 projection fence: a seam that cannot project cannot # certify the candidate's sub-exempt gainers. diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py index 40698aa6f6..4baa4e3b9f 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py @@ -61,8 +61,9 @@ def test_uk_spine_graph_contains_every_manifest_stage() -> None: # copies' childcare re-draw childcare_copy_take_up, and microcosm#1334 # uc_take_up and frs_annual_income_spells; microcosm#1428 the last stage, # trading_allowance_receipts; and company_cars after hmrc_spi_income_spine - # (PolicyEngine/uk-autumn-budget-dashboard-2026#316). - assert len(expected) == 52 + # (PolicyEngine/uk-autumn-budget-dashboard-2026#316); and microcosm#1490 + # spi_employment_shell after company_cars. + assert len(expected) == 53 assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(expected) assert set(expected) <= ids assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(ids) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py index a642c8e223..f363bc8b60 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py @@ -38,3 +38,39 @@ def test_the_employment_stage_reads_the_shared_frs_view() -> None: def test_the_code_tables_are_immutable(mapping) -> None: with pytest.raises(TypeError): mapping[10] = "OTHER" # type: ignore[index] + + +def test_every_adult_employment_status_has_an_occupation_status_group() -> None: + from microcosm.build.uk_runtime.occupation_constants import ( + UK_OCCUPATION_STATUS_GROUP, + ) + + adult_statuses = set(frs_employment.FRS_EMPSTATI_EMPLOYMENT_STATUS.values()) + assert set(UK_OCCUPATION_STATUS_GROUP) == adult_statuses + assert frs_employment.CHILD_EMPLOYMENT_STATUS not in UK_OCCUPATION_STATUS_GROUP + assert set(UK_OCCUPATION_STATUS_GROUP.values()) == { + "EMPLOYEE", + "SELF_EMPLOYED", + "RETIRED", + "OTHER", + } + + +def test_sic_sections_are_ordered_and_disjoint() -> None: + from microcosm.build.uk_runtime.occupation_constants import ( + UK_SIC2007_SECTION_DIVISIONS, + uk_sic2007_sections, + ) + + ranges = list(UK_SIC2007_SECTION_DIVISIONS.items()) + assert [section for section, _ in ranges] == list("ABCDEFGHIJKLMNOPQRSTU") + for (_, (_, last)), (_, (first, _)) in zip(ranges, ranges[1:], strict=False): + assert last < first + assert list(uk_sic2007_sections([0, 1, 4, 47, 85, 99])) == [ + "", + "A", + "", + "G", + "P", + "U", + ] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py index 78688bd0a0..e30ab3d97a 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py @@ -71,6 +71,9 @@ # the income stage writes it, so every later stage reads pay without them # (PolicyEngine/uk-autumn-budget-dashboard-2026#316). "company_cars", + # The employment shell redraws the drawn rows' occupation from that carved + # pay, before the housing shell (microcosm#1490). + "spi_employment_shell", ] HOUSING_SHELL_STAGE_NAMES = [ "spi_housing_shell", @@ -318,6 +321,7 @@ def test_country_stage_plan_assembles_spine_plan(self) -> None: "isa_subscriptions": _identity, "trading_allowance_receipts": _identity, "company_cars": _identity, + "spi_employment_shell": _identity, "childcare_copy_take_up": _identity, "age_tail": _identity, "frs_relationships": _identity, diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py new file mode 100644 index 0000000000..72a4be813e --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py @@ -0,0 +1,269 @@ +"""The SPI employment shell: which rows it redraws, how, and what its receipt and gate say.""" + +from __future__ import annotations + +import copy +import json + +import numpy as np +import pandas as pd +import pytest + +from microcosm.build import load_country_spec +from microcosm.build.uk_runtime.spi_employment_shell import ( + UK_SPI_EMPLOYMENT_SHELL_OPERATION, + UK_SPI_EMPLOYMENT_SHELL_REWRITES, + _assert_stage_parameters, + drawn_rows, + impute_spi_employment_shell, +) +from microcosm.build.uk_runtime.stage_health import uk_stage_health_gate +from test_support.microcosm_build.uk_spi_employment_shell import employment_shell_tables + +STAGE = "spi_employment_shell" + + +@pytest.fixture(scope="module") +def tables(): + return employment_shell_tables() + + +@pytest.fixture(scope="module") +def shell(tables): + person, household, weights = tables + return impute_spi_employment_shell(person, household, weights, boosted_max_iter=60) + + +def _stage(): + return next(s for s in load_country_spec("uk").sources.stages if s.stage == STAGE) + + +def test_the_packaged_stage_matches_the_module_contract() -> None: + stage = _stage() + _assert_stage_parameters(stage) + assert tuple(stage.rewrites) == UK_SPI_EMPLOYMENT_SHELL_REWRITES + assert stage.outputs == () + + +def test_a_drifted_setting_is_refused() -> None: + stage = _stage() + drifted = copy.deepcopy(dict(stage.operations[0].parameters)) + drifted["occupation"]["boosted_weight"] = 1.0 + operation = type(stage.operations[0])( + kind=stage.operations[0].kind, parameters=drifted + ) + changed = type(stage)(**{**stage.__dict__, "operations": (operation,)}) + with pytest.raises(ValueError, match="parameters drifted"): + _assert_stage_parameters(changed) + + +def test_frs_rows_and_undrawn_rows_are_unchanged(tables, shell) -> None: + person, _, _ = tables + person_out, _ = shell + drawn = drawn_rows(person) + pd.testing.assert_frame_equal(person.loc[~drawn], person_out.loc[~drawn]) + untouched = [c for c in person.columns if c not in UK_SPI_EMPLOYMENT_SHELL_REWRITES] + pd.testing.assert_frame_equal(person[untouched], person_out[untouched]) + + +def test_drawn_pay_moves_the_occupation(tables, shell) -> None: + person, _, _ = tables + person_out, _ = shell + drawn = drawn_rows(person) + before = person.loc[drawn, "soc2020_major_group"] + after = person_out.loc[drawn, "soc2020_major_group"] + # The copies' twins are low paid; their drawn pay is high, and in the + # planted ladder the highest pay goes with managers. + assert (before == "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS").mean() < 0.1 + assert (after == "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS").mean() > 0.6 + assert (after != "NONE").all() + + +def test_rows_with_neither_an_occupation_nor_work_keep_none(tables, shell) -> None: + person, _, _ = tables + person_out, receipt = shell + idle = ( + person["person_is_spi_income_recipient"] + & (person["soc2020_major_group"] == "NONE") + & (person["hmrc_spi_pay"] <= 0) + & (person["self_employment_income"] <= 0) + ) + assert idle.any() + assert (person_out.loc[idle, "soc2020_major_group"] == "NONE").all() + assert receipt["drawn"]["kept_no_occupation"] == "3-9" + + +def test_copied_industry_pairs_occur_among_donors_of_the_drawn_group( + tables, shell +) -> None: + person, household, weights = tables + person_out, _ = shell + frs = person["person_household_id"].isin( + household.loc[household["household_support_channel"] == "frs", "household_id"] + ) & (person["soc2020_major_group"] != "NONE") + donor_triples = set( + zip( + person.loc[frs, "soc2020_major_group"], + person.loc[frs, "sic_industry_division"], + person.loc[frs, "employment_sector"], + strict=True, + ) + ) + drawn = drawn_rows(person) + for triple in zip( + person_out.loc[drawn, "soc2020_major_group"], + person_out.loc[drawn, "sic_industry_division"], + person_out.loc[drawn, "employment_sector"], + strict=True, + ): + assert triple in donor_triples + + +def test_draws_are_keyed_on_each_persons_id(tables, shell) -> None: + person, household, weights = tables + person_out, _ = shell + order = np.random.default_rng(3).permutation(len(person)) + shuffled_out, _ = impute_spi_employment_shell( + person.iloc[order], household, weights, boosted_max_iter=60 + ) + pd.testing.assert_frame_equal( + shuffled_out.sort_index(), person_out.sort_index(), check_like=True + ) + + +def test_the_receipt_is_finite_json_with_banded_counts(shell) -> None: + _, receipt = shell + json.dumps(receipt, sort_keys=True, allow_nan=False) + held_out = receipt["held_out"] + assert held_out["status"] == "measured" + assert set(held_out["log_loss"]) == {"model", "boosted", "spline_logit", "marginal"} + assert held_out["calibration_outcome"] == "cross_fitted" + assert receipt["training"]["people"] == 1500 + assert set(receipt["industry_copy"]["levels"]) == { + "group_and_status", + "group", + "everyone", + } + for band in held_out["pay_bands"].values(): + assert band["support"] in {"<3", "3-9", "10-29", "30+"} or band["support"] == 0 + + +def test_too_few_households_per_group_leave_the_evidence_unmeasured() -> None: + person, household, weights = employment_shell_tables(n_frs=18, n_spi=6, seed=5) + person_out, receipt = impute_spi_employment_shell( + person, household, weights, boosted_max_iter=5 + ) + assert receipt["held_out"]["status"] == "not_measured" + assert (person_out.loc[drawn_rows(person), "soc2020_major_group"] != "NONE").all() + + +def test_a_child_status_among_drawn_rows_is_refused(tables) -> None: + person, household, weights = tables + broken = person.copy() + row = np.flatnonzero(drawn_rows(person))[0] + broken.loc[broken.index[row], "employment_status"] = "CHILD" + with pytest.raises(ValueError, match="no occupation status group"): + impute_spi_employment_shell(broken, household, weights, boosted_max_iter=5) + + +def test_an_frs_row_marked_as_an_spi_recipient_is_refused(tables) -> None: + person, household, weights = tables + broken = person.copy() + broken.loc[broken.index[0], "person_is_spi_income_recipient"] = True + with pytest.raises(ValueError, match="FRS-channel row"): + impute_spi_employment_shell(broken, household, weights, boosted_max_iter=5) + + +def test_the_declared_settings_are_the_measured_blend() -> None: + occupation = UK_SPI_EMPLOYMENT_SHELL_OPERATION["occupation"] + assert occupation["boosted_weight"] == 0.5 + assert occupation["boosted"]["learning_rate"] == 0.05 + assert occupation["logit"]["n_knots"] == 6 + assert UK_SPI_EMPLOYMENT_SHELL_OPERATION["industry"]["neighbours"] == 50 + + +# --- the occupation_redraw stage-health gate --------------------------------- + + +def _gate_parameters() -> dict: + gates = load_country_spec("uk").gates + entry = next(e for e in gates.gates if e.id == "uk_stage_spi_employment_shell_fit") + assert (entry.gate, entry.phase) == ("stage_health", "transferred") + assert entry.population_fact_check and entry.evidence_absent_blocks + return dict(entry.parameters) + + +def _evidence(**overrides) -> dict: + held_out = { + "status": "measured", + "log_loss": { + "model": 1.82, + "boosted": 1.83, + "spline_logit": 1.835, + "marginal": 2.12, + }, + "calibration_slope": 1.01, + "calibration_outcome": "cross_fitted", + "pay_band_share_gap_mean": 0.013, + "status_group_share_gap_max": 0.012, + } + held_out.update(overrides) + return {"stage": STAGE, "held_out": held_out} + + +def _gate(evidence: dict): + parameters = _gate_parameters() + return uk_stage_health_gate( + evidence=evidence, + stage=STAGE, + check=parameters["check"], + parameters=parameters, + ) + + +def test_the_gate_passes_the_measured_blend() -> None: + assert _gate(_evidence()).passed + + +@pytest.mark.parametrize( + "overrides, message", + [ + ( + { + "log_loss": { + "model": 2.0, + "boosted": 2.0, + "spline_logit": 2.05, + "marginal": 2.12, + } + }, + "below the constant", + ), + ( + { + "log_loss": { + "model": 1.84, + "boosted": 1.82, + "spline_logit": 1.86, + "marginal": 2.12, + } + }, + "better learner", + ), + ({"calibration_slope": 1.3}, "outside"), + ( + { + "calibration_slope": None, + "calibration_outcome": "cross_fitted_class_rates", + }, + "could not be fitted", + ), + ({"pay_band_share_gap_mean": 0.05}, "pay bands"), + ({"status_group_share_gap_max": 0.05}, "status group"), + ({"status": "not_measured", "reason": "thin"}, "not measured"), + ], +) +def test_each_bound_fails_the_gate(overrides, message) -> None: + result = _gate(_evidence(**overrides)) + assert not result.passed + assert any(message in failure for failure in result.failures) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py index b419b9069b..142a932836 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py @@ -180,6 +180,10 @@ def _apply_pending_roster_transformations( # company cars follow the SPI income stage, whose pay they carve. assert "company_cars" not in roster roster.insert(roster.index("hmrc_spi_income_spine") + 1, "company_cars") + # microcosm#1490 re-mint pending: the employment shell redraws the drawn + # rows' occupation from the pay the company cars carve. + assert "spi_employment_shell" not in roster + roster.insert(roster.index("company_cars") + 1, "spi_employment_shell") # microcosm#1428 re-mint pending: the self-employed's gross receipts run # last. assert "trading_allowance_receipts" not in roster diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 620516d8a0..9e7bf9a82c 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -475,13 +475,13 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: # fingerprint derives from the manifest digest. Editing the spec moves all # three here in the same reviewed change. _UK_GATE_BATTERY_POLICY_SHA256 = ( - "829eaae1a12e19f0c41c737bea0dbdda6448637e977b008bad9ca5c3db357200" + "7329732e070d3c10aef9ea50b9cd330c4187480b2fbcfc0b65ab1146fdfd75df" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "01abc259f99ecdd73bd636102b32482f1f41dc557a5f0bf23d930348c75a8c8d" + "e83191ad38751ba75b8d1ed45352033f3d89851b7a2ec93b01e993a26c9498df" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "215c0fab9e2c77b415633f8f9292a5ff20839662274df7d6d7f1e126417badde" + "8dba276a743e06d300be96dd7e390fea9e56455fae016ac4d0a995fd04e5ae87" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -588,6 +588,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_stage_isa_subscriptions_invariants": ("stage_health", "transferred"), "uk_stage_isa_subscriptions": ("stage_health", "transferred"), "uk_stage_company_cars_invariants": ("stage_health", "transferred"), + "uk_stage_spi_employment_shell_fit": ("stage_health", "transferred"), "uk_stage_frs_take_up_signal": ("stage_health", "assembled"), "uk_stage_frs_person_draws_take_up_signal": ("stage_health", "assembled"), "uk_stage_frs_household_draws_take_up_signal": ("stage_health", "assembled"), @@ -704,6 +705,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_stage_isa_subscriptions_invariants", "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", + "uk_stage_spi_employment_shell_fit", "uk_stage_frs_take_up_signal", "uk_stage_frs_person_draws_take_up_signal", "uk_stage_frs_household_draws_take_up_signal", @@ -942,6 +944,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: "uk_stage_isa_subscriptions", "uk_stage_isa_subscriptions_invariants", "uk_stage_company_cars_invariants", + "uk_stage_spi_employment_shell_fit", "uk_stage_lcfs_consumption_basis", "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_lcfs_consumption_energy_rake", @@ -1009,10 +1012,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: _UK_CERTIFICATION_PART_DIGESTS: Mapping[str, Mapping[str, str]] = { "spine": { "gates_manifest_sha256": ( - "970974c07b1102a208c9ee12962d42d540adc1966789219cb5ea18718000a16e" + "9d9d85efebb2f43ccbac86a3f1075c97a869ae3f46b95cf3ce2fd876a2ffecc8" ), "policy_sha256": ( - "6416dda130412d6ceaeac2450a70befa694cbf582dee609ca34329a56849762b" + "f8eb18ad80403344041a7c8dab73b36bf424ab5c621cf7a146417e34d88f8ee6" ), }, "calibration_seam": { diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index aac1d19e05..60c8f4b618 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -224,13 +224,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 = ( - "829eaae1a12e19f0c41c737bea0dbdda6448637e977b008bad9ca5c3db357200" + "7329732e070d3c10aef9ea50b9cd330c4187480b2fbcfc0b65ab1146fdfd75df" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "01abc259f99ecdd73bd636102b32482f1f41dc557a5f0bf23d930348c75a8c8d" + "e83191ad38751ba75b8d1ed45352033f3d89851b7a2ec93b01e993a26c9498df" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "215c0fab9e2c77b415633f8f9292a5ff20839662274df7d6d7f1e126417badde" + "8dba276a743e06d300be96dd7e390fea9e56455fae016ac4d0a995fd04e5ae87" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "f246388de42654dd68dbbb40c42282001b5b0a8bf48976162bcb1199085cb1d3" @@ -375,6 +375,7 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "uk_stage_isa_subscriptions_invariants": ("stage_health", "transferred", None), "uk_stage_isa_subscriptions": ("stage_health", "transferred", None), "uk_stage_company_cars_invariants": ("stage_health", "transferred", None), + "uk_stage_spi_employment_shell_fit": ("stage_health", "transferred", None), "uk_stage_frs_take_up_signal": ( "stage_health", "assembled", @@ -1477,6 +1478,7 @@ def _gate_battery_payload( "uk_stage_isa_subscriptions_invariants": "isa_subscriptions", "uk_stage_isa_subscriptions": "isa_subscriptions", "uk_stage_company_cars_invariants": "company_cars", + "uk_stage_spi_employment_shell_fit": "spi_employment_shell", "uk_stage_frs_take_up_signal": "frs_take_up", "uk_stage_frs_person_draws_take_up_signal": "frs_person_draws", "uk_stage_frs_household_draws_take_up_signal": "frs_household_draws", diff --git a/test_support/microcosm_build/uk_spi_employment_shell.py b/test_support/microcosm_build/uk_spi_employment_shell.py new file mode 100644 index 0000000000..2999814c70 --- /dev/null +++ b/test_support/microcosm_build/uk_spi_employment_shell.py @@ -0,0 +1,123 @@ +"""Synthetic FRS and SPI tables for the SPI employment shell tests. + +FRS adults' occupation follows their pay, and their industry and sector follow +their occupation. SPI-channel copies draw high pay but keep a low-paid twin's +occupation, industry and sector, so a stage that conditions on the recipient's +own pay moves them into the occupations that pay implies and gives them an +industry from an adult in that occupation. +""" + +from __future__ import annotations + +import numpy as np +import pandas as pd + +_REGIONS = ("LONDON", "NORTH_EAST", "WALES") +#: Pay rank (low to high) -> the planted occupation, industry division, sector. +_LADDER = ( + ("ELEMENTARY", 47, "PRIVATE"), + ("SALES_AND_CUSTOMER_SERVICE", 47, "PRIVATE"), + ("SKILLED_TRADES", 43, "PRIVATE"), + ("ASSOCIATE_PROFESSIONAL", 86, "PUBLIC"), + ("PROFESSIONAL", 85, "PUBLIC"), + ("MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS", 70, "PRIVATE"), +) + + +def employment_shell_tables(n_frs: int = 1500, n_spi: int = 300, seed: int = 0): + """FRS adults whose occupation follows pay; SPI copies with a low-paid twin's. + + Returns ``(person, household, household_weights)``. Each household has one + adult and one child; every SPI household copies an FRS household (its + ``household_source_id``), its adult is an SPI income recipient with high + drawn pay and the twin's low-paid occupation, industry and sector. A few + SPI adults draw no pay or profit and had no occupation, so they keep NONE. + """ + + rng = np.random.default_rng(seed) + frs_pay = rng.lognormal(10.0, 0.7, n_frs) + rank = np.searchsorted(np.sort(frs_pay), frs_pay) / n_frs + level = np.minimum((rank * len(_LADDER)).astype(int), len(_LADDER) - 1) + noisy = np.where( + rng.random(n_frs) < 0.1, rng.integers(0, len(_LADDER), n_frs), level + ) + twins = rng.integers(0, n_frs, n_spi) + # The copies' twins are low paid: their occupation sits at the bottom. + twins = np.argsort(frs_pay)[: max(n_spi, 1)][rng.integers(0, max(n_spi, 1), n_spi)] + n = n_frs + n_spi + household_id = np.arange(1, n + 1) + channel = np.array(["frs"] * n_frs + ["spi"] * n_spi) + source = np.concatenate([household_id[:n_frs], household_id[twins]]) + region = np.concatenate( + [rng.choice(_REGIONS, n_frs), rng.choice(_REGIONS, n_frs)[twins]] + ) + household = pd.DataFrame( + { + "household_id": household_id, + "household_support_channel": channel, + "household_source_id": source, + "region": region, + } + ) + weights = np.concatenate([rng.uniform(500, 1500, n_frs), rng.uniform(5, 50, n_spi)]) + + occupation = np.array([step[0] for step in _LADDER], dtype=object)[noisy] + division = np.array([step[1] for step in _LADDER])[noisy] + sector = np.array([step[2] for step in _LADDER], dtype=object)[noisy] + spi_pay = rng.lognormal(12.3, 0.4, n_spi) + workless = np.zeros(n_spi, dtype=bool) + workless[:5] = True + adult = pd.DataFrame( + { + "person_household_id": household_id, + "age": np.concatenate( + [rng.integers(20, 70, n_frs), rng.integers(30, 70, n_spi)] + ), + "gender": rng.choice(["MALE", "FEMALE"], n), + "employment_status": np.where( + rng.random(n) < 0.85, "FT_EMPLOYED", "FT_SELF_EMPLOYED" + ), + "employment_income": np.concatenate( + [frs_pay, np.where(workless, 0.0, spi_pay)] + ), + "hmrc_spi_pay": np.concatenate( + [np.zeros(n_frs), np.where(workless, 0.0, spi_pay)] + ), + "self_employment_income": np.zeros(n), + "savings_interest_income": rng.exponential(200.0, n), + "dividend_income": np.zeros(n), + "private_pension_income": np.zeros(n), + "person_is_spi_income_recipient": channel == "spi", + "soc2020_major_group": np.concatenate( + [occupation, np.where(workless, "NONE", occupation[twins])] + ), + "sic_industry_division": np.concatenate( + [division, np.where(workless, 0, division[twins])] + ).astype(np.int64), + "employment_sector": np.concatenate( + [sector, np.where(workless, "NOT_EMPLOYED", sector[twins])] + ), + } + ) + adult.loc[n_frs + np.flatnonzero(workless), "employment_status"] = "OTHER_INACTIVE" + child = pd.DataFrame( + { + "person_household_id": household_id, + "age": np.full(n, 8), + "gender": rng.choice(["MALE", "FEMALE"], n), + "employment_status": "CHILD", + "employment_income": 0.0, + "hmrc_spi_pay": 0.0, + "self_employment_income": 0.0, + "savings_interest_income": 0.0, + "dividend_income": 0.0, + "private_pension_income": 0.0, + "person_is_spi_income_recipient": False, + "soc2020_major_group": "NONE", + "sic_industry_division": np.zeros(n, dtype=np.int64), + "employment_sector": "NOT_EMPLOYED", + } + ) + person = pd.concat([adult, child], ignore_index=True) + person.insert(0, "person_id", np.arange(1, len(person) + 1) * 10) + return person, household, weights diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index fc44791de7..c0fab11b29 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -166,6 +166,9 @@ from microcosm.build.uk_runtime.spi_benefit_coherence import ( UKSPIBenefitCoherenceStageTransform, ) +from microcosm.build.uk_runtime.spi_employment_shell import ( + UKSPIEmploymentShellStageTransform, +) from microcosm.build.uk_runtime.spi_housing_shell import ( UKSPIHousingShellStageTransform, ) @@ -212,7 +215,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 = 52 +UK_FIXTURE_STAGE_COUNT = 53 _QRF_ESTIMATORS = 4 # These are the complete object-string surface observed in the unchanged @@ -2360,6 +2363,9 @@ def capture_root(frame: Frame) -> Frame: donor_table=spi_donor, source_targets=income_targets, ), + "spi_employment_shell": UKSPIEmploymentShellStageTransform( + stage=stages["spi_employment_shell"], boosted_max_iter=_QRF_ESTIMATORS + ), "spi_housing_shell": UKSPIHousingShellStageTransform( stage=stages["spi_housing_shell"], n_estimators=_QRF_ESTIMATORS ), From 9a183742f911f0e4ad492bebe289fc9962fc2eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 15:21:22 +0000 Subject: [PATCH 4/7] Draw the SOC 2020 sub-major group within the major group from the APS (#1490) aps_occupation draws each person's soc2020_sub_major_group within the major group that the FRS carry and the SPI employment shell settle. The donors are the Annual Population Survey's adults with a SOC 2020 minor group, April 2024 to March 2025 (UK Data Service SN 9408, End User Licence): the main job's group for people in employment, the last job's otherwise. Employees without a pay figure leave the donors; those with one carry the income weight PIWTA22, and everyone else the person weight PWTA22. Each major group gets microcosm- fit's CategoricalClassifier blend over its sub-major groups. The predictors are age (capped at 80), sex, region, employment-status group, annual pay and SIC 2007 section, the set that held out best on the APS. The tab is caller-supplied (--aps-tab) and pinned by size and sha256. Region comes from GOVTOF, which is numeric and agrees with GOR9DCENSUS2021 on every record; the pinned reader blanks string columns. Draws key on person_source_id, so an undrawn SPI copy draws its FRS twin's group. SPI income recipients key on their own person_id under a separate salt. A person with no major group keeps NONE. The receipt records: - the cleaning's drops and the donors by major group; - held-out evidence on five person folds per major group: the pooled log loss of the model, each learner and the constant; each group's slope; and share gaps within pay bands, regions, age bands and status groups; - the FRS rows' expected shares against the donors'. Two new gates. A stage-health gate, uk_stage_aps_occupation_fit (check sub_major_draw), holds the evidence to proposed bounds. A terminal gate, uk_soc2020_sub_major_group_enum_domain, keeps the column inside the engine's enum. The column joins the export allow-list, and this commit retires its signed NONE default. microcosm-fit's CategoricalClassifier gains unseen_categories="ignore", which gives a level the fit never saw no indicator, as the experiment's one-hot encoding did. It also gains unseen_category_rows; the receipt counts the households that held one. The gates move the battery's three vintage digests and the spine and release-cut parts' two each. The coverage manifest's source digests are regenerated. receipt_counts records that SN 9408's catalogue entry sets no condition beyond the End User Licence (checked 2026-11-04). The H2 fixture tool gains a synthetic APS donor (three per sub-major group) and the 54-stage count; the fixture itself is regenerated once the policyengine-uk bump is measured. Co-Authored-By: Claude Opus 5.5 --- .../1490-uk-occupation-sub-major.added.md | 3 + docs/uk-full-build-graph.md | 7 +- .../src/microcosm/build/source_manifest.py | 2 + .../spec_engine/schema/sources.schema.json | 368 ++++++++ .../src/microcosm/build/uk/gates.json | 35 + .../uk/release_input_coverage_manifest.json | 50 +- .../src/microcosm/build/uk/source_stages.json | 164 ++++ .../src/microcosm/build/uk/spec/sources.yaml | 139 +++ .../build/uk_runtime/aps_occupation.py | 810 ++++++++++++++++++ .../build/uk_runtime/battery_bindings.py | 5 + .../build/uk_runtime/calibration_run.py | 2 + .../src/microcosm/build/uk_runtime/graph.py | 20 + .../build/uk_runtime/graph_kernels.py | 21 + .../build/uk_runtime/occupation_constants.py | 48 ++ .../build/uk_runtime/receipt_counts.py | 12 +- .../microcosm/build/uk_runtime/spine_build.py | 26 + .../build/uk_runtime/stage_health.py | 133 +++ .../build/uk_runtime/terminal_gates.py | 1 + .../engine/uk/test_uk_occupation_constants.py | 17 + .../engine_free/shared/test_country_spec.py | 8 +- .../engine_free/uk/test_uk_aps_occupation.py | 451 ++++++++++ .../uk/test_uk_battery_bindings.py | 5 +- .../tests/engine_free/uk/test_uk_frs_spine.py | 6 + .../tests/engine_free/uk/test_uk_graph.py | 6 +- .../uk/test_uk_occupation_constants.py | 21 + .../uk/test_uk_occupation_resources.py | 48 ++ .../engine_free/uk/test_uk_source_stages.py | 5 +- .../uk/test_uk_spine_acceptance_receipt.py | 4 + .../src/microcosm/data/contract.py | 20 +- .../tests/engine_free/shared/test_contract.py | 13 +- .../src/microcosm/fit/categorical.py | 53 +- .../engine_free/shared/test_categorical.py | 17 + .../adapters/policyengine_uk_concepts.py | 7 - .../microcosm_build/uk_aps_occupation.py | 171 ++++ tools/graph_uk_spine_fixture.py | 52 +- 35 files changed, 2685 insertions(+), 65 deletions(-) create mode 100644 changelog.d/1490-uk-occupation-sub-major.added.md create mode 100644 packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py create mode 100644 packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py create mode 100644 packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py create mode 100644 test_support/microcosm_build/uk_aps_occupation.py diff --git a/changelog.d/1490-uk-occupation-sub-major.added.md b/changelog.d/1490-uk-occupation-sub-major.added.md new file mode 100644 index 0000000000..9a91904836 --- /dev/null +++ b/changelog.d/1490-uk-occupation-sub-major.added.md @@ -0,0 +1,3 @@ +A new UK spine stage, `aps_occupation`, draws each person's SOC 2020 sub-major group, policyengine-uk's `soc2020_sub_major_group`, within the major group the earlier stages settle (microcosm#1490). The FRS codes the major group only; the donors are the Annual Population Survey's adults with a minor group, April 2024 to March 2025 (UK Data Service SN 9408, a caller-supplied licensed tab pinned by sha256 and passed with `--aps-tab`). Each major group gets its own `CategoricalClassifier` blend over its sub-major groups, on age, sex, region, employment-status group, annual pay and SIC 2007 section, the predictors both surveys record alike. A person with no major group keeps NONE, and the signed NONE default for the column is retired. + +Draws are keyed on `person_source_id`, so an SPI copy draws its FRS twin's group, except for the SPI income recipients, which key on their own `person_id`. The receipt records held-out evidence on five person folds per major group (the APS file has no household identifier) and the FRS rows' expected shares against the donors'. A stage-health gate, `uk_stage_aps_occupation_fit`, holds them to declared bounds, and a terminal gate, `uk_soc2020_sub_major_group_enum_domain`, keeps the column inside the engine's enum. microcosm-fit's classifier gains `unseen_categories="ignore"`, which gives a category the fit never saw no indicator, and counts the rows that held one. diff --git a/docs/uk-full-build-graph.md b/docs/uk-full-build-graph.md index 244a753c4e..7c21814bf0 100644 --- a/docs/uk-full-build-graph.md +++ b/docs/uk-full-build-graph.md @@ -52,7 +52,8 @@ To include raw spine construction in the same execution, pass `--spine-request / "--nts-ticket-tab", "/data/nts/ticket.tab", "--lcfs-hh-tab", "/data/lcfs/household.tab", "--lcfs-person-tab", "/data/lcfs/person.tab", - "--etb-tab", "/data/etb/household.tab" + "--etb-tab", "/data/etb/household.tab", + "--aps-tab", "/data/aps/apsp_a24m25_eul_pwta22.tab" ] ``` @@ -68,11 +69,11 @@ For smaller outputs, add `--dataset-households 150000` to use the common informe ## Graph owners and shared contracts -The spine graph is the 48-stage source roster declared by the UK spec, built by `uk_runtime.spine_build` (the spine tool moved into the package; `tools/build_uk_frs_spine.py` is a six-line shim over it). The superseded `frs_hmrc_retained_leaves` and `hmrc_spi_income` stages and the `UK_SPINE_EXCLUSIONS` list that hid them are removed; the active HMRC path is `frs_hmrc_spine_leaves`, `spi_support_channel`, `spi_income_band_donors` and `hmrc_spi_income_spine`, and the FRS HMRC leaf columns come from `uk_runtime.frs_hmrc_source`. The spine's assembled and transferred gate batteries are graph nodes (`uk_runtime.graph_evidence`); stage evidence and fit-weight records are read back from the content store through the shared `stage_evidence` artifact rather than from in-memory collectors; the HMRC replay sidecar is rebuilt from the SPI stage's checkpoint metadata; the spine sidecar records the operation inventory and the graph manifest, and the graph manifest is saved as `spine.graph.json` under the checkpoint root. +The spine graph is the 54-stage source roster declared by the UK spec, built by `uk_runtime.spine_build` (the spine tool moved into the package; `tools/build_uk_frs_spine.py` is a six-line shim over it). The superseded `frs_hmrc_retained_leaves` and `hmrc_spi_income` stages and the `UK_SPINE_EXCLUSIONS` list that hid them are removed; the active HMRC path is `frs_hmrc_spine_leaves`, `spi_support_channel`, `spi_income_band_donors` and `hmrc_spi_income_spine`, and the FRS HMRC leaf columns come from `uk_runtime.frs_hmrc_source`. The spine's assembled and transferred gate batteries are graph nodes (`uk_runtime.graph_evidence`); stage evidence and fit-weight records are read back from the content store through the shared `stage_evidence` artifact rather than from in-memory collectors; the HMRC replay sidecar is rebuilt from the SPI stage's checkpoint metadata; the spine sidecar records the operation inventory and the graph manifest, and the graph manifest is saved as `spine.graph.json` under the checkpoint root. | Operation | Graph owner | | --- | --- | -| Raw FRS and donor preparation, enrichment, support channels | The 48 UK spine stage nodes and their declared composite operations | +| Raw FRS and donor preparation, enrichment, support channels | The 54 UK spine stage nodes and their declared composite operations | | Assembled and transferred spine gates | `spine.gates.assembled`, `spine.gates.transferred` | | Bound checkpoint admission | `uk.full.spine_checkpoint`, when resuming a saved spine | | Pool sample and mass normalization | `uk.full.sample`, `uk.full.normalize` | diff --git a/packages/microcosm-build/src/microcosm/build/source_manifest.py b/packages/microcosm-build/src/microcosm/build/source_manifest.py index 802083d274..2b1d7d8c02 100644 --- a/packages/microcosm-build/src/microcosm/build/source_manifest.py +++ b/packages/microcosm-build/src/microcosm/build/source_manifest.py @@ -79,6 +79,7 @@ "clone_records", "clean_nts_travel_tables", "clean_was_lisa_donor", + "clean_aps_occupation_table", # microcosm#1415: ISA subscriptions per adult and the Lifetime ISA anchor. "allocate_isa_subscribers", "anchor_lifetime_isa_ownership", @@ -166,6 +167,7 @@ "impute_cell_means", "impute_spi_housing_shell", "impute_spi_employment_shell", + "impute_soc2020_sub_major_group", "impute_housing_assistance_to_puf_support", "impute_other_health_insurance_premiums_to_puf_support", "impute_prior_year_income_to_puf_support", 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 4a4b153565..f506fd2041 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 @@ -8989,6 +8989,374 @@ } } }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "lowercase_columns", + "adult_age", + "age_cap", + "pay_weeks", + "columns", + "codes" + ], + "properties": { + "kind": { + "const": "clean_aps_occupation_table" + }, + "lowercase_columns": { + "type": "boolean" + }, + "adult_age": { + "type": "integer", + "minimum": 0 + }, + "age_cap": { + "type": "integer", + "minimum": 0 + }, + "pay_weeks": { + "type": "integer", + "minimum": 1 + }, + "columns": { + "type": "object", + "additionalProperties": false, + "required": [ + "age", + "sex", + "region", + "economic_activity", + "status", + "main_minor_group", + "last_minor_group", + "weekly_pay", + "person_weight", + "income_weight", + "main_section", + "last_section" + ], + "properties": { + "age": { + "type": "string", + "minLength": 1 + }, + "sex": { + "type": "string", + "minLength": 1 + }, + "region": { + "type": "string", + "minLength": 1 + }, + "economic_activity": { + "type": "string", + "minLength": 1 + }, + "status": { + "type": "string", + "minLength": 1 + }, + "main_minor_group": { + "type": "string", + "minLength": 1 + }, + "last_minor_group": { + "type": "string", + "minLength": 1 + }, + "weekly_pay": { + "type": "string", + "minLength": 1 + }, + "person_weight": { + "type": "string", + "minLength": 1 + }, + "income_weight": { + "type": "string", + "minLength": 1 + }, + "main_section": { + "type": "string", + "minLength": 1 + }, + "last_section": { + "type": "string", + "minLength": 1 + } + } + }, + "codes": { + "type": "object", + "additionalProperties": false, + "required": [ + "in_employment", + "under_16", + "employee", + "sex", + "region", + "status_group", + "other_status_group", + "sections" + ], + "properties": { + "in_employment": { + "type": "integer" + }, + "under_16": { + "type": "integer" + }, + "employee": { + "type": "integer" + }, + "sex": { + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "string" + } + }, + "region": { + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "string" + } + }, + "status_group": { + "type": "object", + "minProperties": 1, + "additionalProperties": { + "type": "string" + } + }, + "other_status_group": { + "type": "string" + }, + "sections": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + } + } + } + } + }, + { + "type": "object", + "additionalProperties": false, + "required": [ + "kind", + "output", + "within", + "rows", + "identity", + "seed", + "predictors", + "categorical_predictors", + "unseen_categories", + "arcsinh_columns", + "arcsinh_scale", + "boosted", + "logit", + "boosted_weight", + "evidence" + ], + "properties": { + "kind": { + "const": "impute_soc2020_sub_major_group" + }, + "output": { + "type": "string" + }, + "within": { + "type": "string" + }, + "rows": { + "type": "string" + }, + "identity": { + "type": "string" + }, + "seed": { + "type": "integer" + }, + "predictors": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "categorical_predictors": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "unseen_categories": { + "enum": [ + "refuse", + "ignore" + ] + }, + "arcsinh_columns": { + "type": "array", + "minItems": 1, + "items": { + "type": "string" + } + }, + "arcsinh_scale": { + "type": "number", + "exclusiveMinimum": 0 + }, + "boosted": { + "type": "object", + "additionalProperties": false, + "required": [ + "learning_rate", + "max_leaf_nodes", + "min_samples_leaf", + "l2_regularization", + "early_stopping", + "validation_fraction", + "n_iter_no_change", + "max_iter" + ], + "properties": { + "learning_rate": { + "type": "number", + "exclusiveMinimum": 0 + }, + "max_leaf_nodes": { + "type": "integer", + "minimum": 2 + }, + "min_samples_leaf": { + "type": "integer", + "minimum": 1 + }, + "l2_regularization": { + "type": "number", + "minimum": 0 + }, + "early_stopping": { + "type": "boolean" + }, + "validation_fraction": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1 + }, + "n_iter_no_change": { + "type": "integer", + "minimum": 1 + }, + "max_iter": { + "type": "integer", + "minimum": 1 + } + } + }, + "logit": { + "type": "object", + "additionalProperties": false, + "required": [ + "n_knots", + "degree", + "knots", + "extrapolation", + "penalty_c", + "solver", + "max_iter" + ], + "properties": { + "n_knots": { + "type": "integer", + "minimum": 2 + }, + "degree": { + "type": "integer", + "minimum": 1 + }, + "knots": { + "enum": [ + "quantile", + "uniform" + ] + }, + "extrapolation": { + "enum": [ + "constant", + "linear", + "continue", + "error" + ] + }, + "penalty_c": { + "type": "number", + "exclusiveMinimum": 0 + }, + "solver": { + "type": "string" + }, + "max_iter": { + "type": "integer", + "minimum": 1 + } + } + }, + "boosted_weight": { + "type": "number", + "minimum": 0, + "maximum": 1 + }, + "evidence": { + "type": "object", + "additionalProperties": false, + "required": [ + "folds", + "grouping", + "pay_band_quantiles", + "age_band_edges" + ], + "properties": { + "folds": { + "type": "integer", + "minimum": 2 + }, + "grouping": { + "enum": [ + "person", + "household" + ] + }, + "pay_band_quantiles": { + "type": "array", + "minItems": 1, + "items": { + "type": "number", + "exclusiveMinimum": 0, + "exclusiveMaximum": 1 + } + }, + "age_band_edges": { + "type": "array", + "minItems": 1, + "items": { + "type": "integer" + } + } + } + } + } + }, { "type": "object", "additionalProperties": false, diff --git a/packages/microcosm-build/src/microcosm/build/uk/gates.json b/packages/microcosm-build/src/microcosm/build/uk/gates.json index 5e36020f40..cd07a3055a 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -1097,6 +1097,28 @@ }, "notes": "Stage-time check of the spi_employment_shell receipt's held-out evidence (microcosm#1490): five folds dealing whole FRS households, scored on the FRS adults the occupation model trains on. It fails when the evidence was not measured; when the model's out-of-fold log loss is not at least minimum_log_loss_gain below the constant's (the training folds' class shares); when the blend's log loss exceeds its better learner's by more than maximum_blend_log_loss_excess; when the calibration slope (1 when the probabilities spread as much as the outcomes do) falls outside calibration_slope_bounds or the Platt fit fell back to class rates; when the weighted mean gap between predicted and observed occupation shares within the pay bands exceeds maximum_pay_band_share_gap; or when the largest gap within a status group exceeds maximum_status_group_share_gap. The bounds sit wide of the blend measured on FRS 2024-25 coded adults: a log-loss gain of 0.30, a slope of 1.01, a pay-band gap of 0.013, status-group gaps of at most 0.012, and a log loss 0.010 below its better learner. A population fact check: a synthetic smoke build records it without blocking, since a fixture of a few households cannot fit the population's occupation model." }, + { + "id": "uk_stage_aps_occupation_fit", + "gate": "stage_health", + "phase": "transferred", + "criticality": "release_blocking", + "evidence_absent_blocks": true, + "population_fact_check": true, + "parameters": { + "stage": "aps_occupation", + "check": "sub_major_draw", + "minimum_log_loss_gain": 0.25, + "calibration_slope_bounds": [ + 0.85, + 1.15 + ], + "maximum_pay_band_share_gap": 0.02, + "maximum_region_share_gap": 0.02, + "maximum_blend_log_loss_excess": 0.005, + "maximum_frame_share_gap": 0.1 + }, + "notes": "Stage-time check of the aps_occupation receipt's held-out evidence (microcosm#1490): within each major group, five stratified folds by person (the APS End User Licence file has no household identifier), scored on the APS donors. It fails when the evidence was not measured; when the model's out-of-fold log loss, pooled over the major groups by donor weight, is not at least minimum_log_loss_gain below the constant's (each group's training folds' class shares); when the blend's pooled log loss exceeds its better learner's by more than maximum_blend_log_loss_excess; when a major group's calibration slope falls outside calibration_slope_bounds or its Platt fit fell back to class rates; when the pooled gap between predicted and observed sub-major shares within the pay bands exceeds maximum_pay_band_share_gap, or within the regions maximum_region_share_gap; or when, in a major group resting on at least three FRS households, the FRS rows' expected sub-major shares miss the donors' by more than maximum_frame_share_gap (total variation), which bounds how far the FRS's own mix of age, sex, region, status, pay and section within a group moves the draw from the APS. The bounds sit wide of the stage measured on the APS April 2024 - March 2025 donors and FRS 2024-25 adults: a pooled log-loss gain of 0.37 (0.553 against 0.927), slopes of 0.96 to 1.01, a pay-band gap of 0.003, a region gap of 0.005, a log loss 0.006 below its better learner, and FRS rows' expected shares within 0.060 of the donors' (professional occupations; the other groups within 0.047). A population fact check: a synthetic smoke build records it without blocking, since a fixture of a few donors cannot fit the population's model." + }, { "id": "uk_release_input_coverage", "gate": "release_input_coverage", @@ -1448,6 +1470,7 @@ "person.salary_sacrifice_reported", "person.sic_industry_division", "person.soc2020_major_group", + "person.soc2020_sub_major_group", "person.stands_as_sole_owner_or_partner_of_company", "person.statutory_paternity_pay", "person.student_loan_balance", @@ -1663,6 +1686,18 @@ }, "notes": "The person SOC 2020 major group must remain inside the PolicyEngine-UK SOC2020MajorGroup enum domain. Checked on the frame the release ships, after every stage that writes the column: frs_employment carries the FRS code, and a later stage may redraw it (microcosm#1490)." }, + { + "id": "uk_soc2020_sub_major_group_enum_domain", + "gate": "enum_domain", + "phase": "terminal", + "criticality": "release_blocking", + "parameters": { + "columns": [ + "soc2020_sub_major_group" + ] + }, + "notes": "The person SOC 2020 sub-major group must remain inside the PolicyEngine-UK SOC2020SubMajorGroup enum domain. Checked on the frame the release ships, after aps_occupation draws it within each person's major group (microcosm#1490)." + }, { "id": "uk_council_tax_band_domain_terminal", "gate": "enum_domain", 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 d19af9bad1..b616d6cfe3 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 @@ -472,7 +472,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -495,7 +495,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -518,7 +518,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -540,7 +540,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -570,7 +570,7 @@ "uc_is_in_gainful_self_employment" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "The FRS job record's company car answers through frs_spine's carriers (EXPBEN01, EXPBEN03, CARVAL, FUELTYP, CARCON, CARAMT), WAS round-8 company cars' list prices, and HMRC's 2024-25 company car recipients by CO2 band (Table 2A) and fuel (Table 2C), via the vendored facts", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" @@ -599,7 +599,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -619,7 +619,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -641,7 +641,7 @@ "required_mass_change_reason": "High-value home support divides every owner household in the top value stratum of its region into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "Microcosm structural operator (microcosm#1240 fix 1); no publisher input", "survey": "Family Resources Survey 2024-25 and SPI synthetic support, after the WAS wealth draw and the regional property uprating" @@ -662,7 +662,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -686,7 +686,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "6a2ba5e3e43c6d7936416552aadc716729b902dcac24b97093ae8ccf06cf8a8f", @@ -776,7 +776,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -803,7 +803,7 @@ "required_mass_change_reason": "ISA subscriptions per adult from HMRC's ISA tables on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "HMRC Individual Savings Account statistics Tables 9.4, 9.6 and 9.7 to 9.9, the cash ISA limit reduction impact note and Lifetime ISA Table 1a, via the vendored facts; Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "HMRC Annual savings statistics (September 2026 release); Wealth and Assets Survey round 8" @@ -873,7 +873,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "UK Data Service SN 9603 Living Costs and Food Survey 2024-25 (2nd edition) household/person tabs and the vendored Chronicle facts for NEED 2024 mean kWh, DESNZ Energy Trends and QEP average prices paid for calendar 2024, road-fuel outturn (DESNZ, HMRC, ONS Consumer Trends) and road fuel by vehicle type (DESNZ), ONS Consumer Trends household spending by COICOP division, the DfT VEH1103 licensed-car stock, NTS bus use, the NTS private cars (UK Data Service SN 5340, End User Licence; the vehicle and household tabs, survey years 2022-2024) for the zero-emission share by income fifth and the household-paid road-fuel mix, and the DfT and devolved bus finance tables and fares indices.", "survey": "Living Costs and Food Survey 2024-25" @@ -899,7 +899,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -919,7 +919,7 @@ "required_mass_change_reason": "Private-school attendance stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "policyengine-uk attends_private_school (the gov.simulation.private_school_vat attendance rates and factor), evaluated by the pinned engine", "survey": "policyengine-uk private-school attendance imputation, stored at the spine's weights" @@ -942,7 +942,7 @@ "property_finance_costs" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/property-rental-income-statistics", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Property Rental Income Statistics 2026 (tax year 2024-25)" @@ -963,7 +963,7 @@ "required_mass_change_reason": "Annual property purchases imputed on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "https://www.gov.uk/government/statistics/uk-stamp-tax-statistics", "survey": "HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected 11 March 2026), Tables 6b, 8a and 8b" @@ -986,7 +986,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "uk/high_value_home_value_knots.json, built by tools/build_uk_high_value_home_stock.py from PolicyEngine/chronicle#343's registrations", "survey": "HM Land Registry Price Paid latest sales uprated with the UK House Price Index, owner-weighted by region (the dense value node's knots, region level)" @@ -1010,7 +1010,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "MHCLG dwellings and the UK House Price Index regional average price averaged over the twelve months of calendar 2024 from the July 2026 full file, the frame's valuation basis, so the engine's annual uprating from 2024 projects the value once (microcosm#1240 fix 5).", "survey": "Public regional property reference" @@ -1038,7 +1038,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -1071,7 +1071,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -1094,7 +1094,7 @@ "student_loan_balance" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "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" @@ -1114,7 +1114,7 @@ "required_mass_change_reason": "Self-employed gross receipts stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "self_employment_income after the SPI income stage; HMRC's published gainers of the raise to GBP 3,000, about 400,000 taxpayers with a lower bill by about GBP 380 on average", "survey": "The self-employed's own profit on the final spine, and HMRC's policy paper on the Budget 2026 trading allowance raise (calibration)" @@ -1136,7 +1136,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -1175,7 +1175,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": "28096b69c17e11048bd766f703af89bd06cc16f490ea9cdca4dcdf7f11e15bc4", + "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index 07413cbca8..72d46846c2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -2974,6 +2974,170 @@ "stage": "spi_employment_shell", "survey": "Family Resources Survey 2024-25" }, + { + "artifacts": [ + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-9408-1", + "filename": "apsp_a24m25_eul_pwta22.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "aps_person_tab", + "runtime_sha256_required": true, + "sha256": "8b4327d3c331b18cf1b1e16485489645f5f57562cca0555315a520c1592b56af", + "size_bytes": 257997154, + "ukds_study_number": 9408 + } + ], + "grain": "person", + "notes": "Runs after spi_employment_shell, which settles every row's SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job's for people in employment (ILODEFR 1), the last job's otherwise, as the FRS records the main or last job. An employee's pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay (weekly pay times 52, arcsinh in the logit) and SIC 2007 section, the predictors both surveys record alike; a section the group's donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS's own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin's group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds' class shares; each group's calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows' expected sub-major shares against the donors' within each major group, with counts banded by the shared disclosure rules.", + "operations": [ + { + "adult_age": 16, + "age_cap": 80, + "codes": { + "employee": 1, + "in_employment": 1, + "other_status_group": "OTHER", + "region": { + "1": "NORTH_EAST", + "10": "SOUTH_WEST", + "11": "WALES", + "12": "SCOTLAND", + "13": "NORTHERN_IRELAND", + "2": "NORTH_WEST", + "3": "NORTH_WEST", + "4": "YORKSHIRE", + "5": "EAST_MIDLANDS", + "6": "WEST_MIDLANDS", + "7": "EAST_OF_ENGLAND", + "8": "LONDON", + "9": "SOUTH_EAST" + }, + "sections": [ + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U" + ], + "sex": { + "1": "MALE", + "2": "FEMALE" + }, + "status_group": { + "1": "EMPLOYEE", + "16": "RETIRED", + "2": "SELF_EMPLOYED", + "24": "RETIRED" + }, + "under_16": 26 + }, + "columns": { + "age": "AGE", + "economic_activity": "ILODEFR", + "income_weight": "PIWTA22", + "last_minor_group": "SC20LMN", + "last_section": "INDS07L", + "main_minor_group": "SC20MMN", + "main_section": "INDS07M", + "person_weight": "PWTA22", + "region": "GOVTOF", + "sex": "SEX", + "status": "INECAC05", + "weekly_pay": "GRSSWK" + }, + "kind": "clean_aps_occupation_table", + "lowercase_columns": true, + "pay_weeks": 52 + }, + { + "arcsinh_columns": [ + "employment_income" + ], + "arcsinh_scale": 1000, + "boosted": { + "early_stopping": true, + "l2_regularization": 1, + "learning_rate": 0.05, + "max_iter": 500, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "n_iter_no_change": 20, + "validation_fraction": 0.2 + }, + "boosted_weight": 0.5, + "categorical_predictors": [ + "gender", + "region", + "status_group", + "sic_section" + ], + "evidence": { + "age_band_edges": [ + 25, + 35, + 45, + 55, + 65 + ], + "folds": 5, + "grouping": "person", + "pay_band_quantiles": [ + 0.5, + 0.8, + 0.9 + ] + }, + "identity": "person_source_id_or_spi_recipient_person_id", + "kind": "impute_soc2020_sub_major_group", + "logit": { + "degree": 3, + "extrapolation": "constant", + "knots": "quantile", + "max_iter": 3000, + "n_knots": 6, + "penalty_c": 1, + "solver": "lbfgs" + }, + "output": "soc2020_sub_major_group", + "predictors": [ + "age", + "gender", + "region", + "status_group", + "employment_income", + "sic_section" + ], + "rows": "people_with_a_major_group", + "seed": 0, + "unseen_categories": "ignore", + "within": "soc2020_major_group" + } + ], + "outputs": [ + "soc2020_sub_major_group" + ], + "source": "Office for National Statistics, Annual Population Survey, April 2024 - March 2025, UK Data Service SN 9408 (End User Licence), DOI 10.5255/UKDA-SN-9408-1; local licensed person tab; the SOC 2020 minor group of the main job, or of the last job for people not in work (microcosm#1490).", + "stage": "aps_occupation", + "survey": "Annual Population Survey, April 2024 - March 2025" + }, { "stage": "spi_housing_shell", "survey": "Family Resources Survey 2024-25", 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 5f3082dd48..99e96c273c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -2518,6 +2518,145 @@ stages: - sic_industry_division - employment_sector notes: 'Runs after company_cars, so the SPI-drawn rows'' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region, falling back to the group and then to all adults where a cell holds fewer; so occupation and industry stay a pair that occurs. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' +- stage: aps_occupation + survey: Annual Population Survey, April 2024 - March 2025 + source: Office for National Statistics, Annual Population Survey, April 2024 - March 2025, UK Data Service SN 9408 (End User Licence), DOI 10.5255/UKDA-SN-9408-1; local licensed person tab; the SOC 2020 minor group of the main job, or of the last job for people not in work (microcosm#1490). + grain: person + artifacts: + - role: aps_person_tab + kind: private_microdata + ukds_study_number: 9408 + doi: 10.5255/UKDA-SN-9408-1 + filename: apsp_a24m25_eul_pwta22.tab + sha256: 8b4327d3c331b18cf1b1e16485489645f5f57562cca0555315a520c1592b56af + size_bytes: 257997154 + access: private_local_input + locator: caller-supplied local input + runtime_sha256_required: true + operations: + - kind: clean_aps_occupation_table + lowercase_columns: true + adult_age: 16 + age_cap: 80 + pay_weeks: 52 + columns: + age: AGE + sex: SEX + region: GOVTOF + economic_activity: ILODEFR + status: INECAC05 + main_minor_group: SC20MMN + last_minor_group: SC20LMN + weekly_pay: GRSSWK + person_weight: PWTA22 + income_weight: PIWTA22 + main_section: INDS07M + last_section: INDS07L + codes: + in_employment: 1 + under_16: 26 + employee: 1 + sex: + '1': MALE + '2': FEMALE + region: + '1': NORTH_EAST + '2': NORTH_WEST + '3': NORTH_WEST + '4': YORKSHIRE + '5': EAST_MIDLANDS + '6': WEST_MIDLANDS + '7': EAST_OF_ENGLAND + '8': LONDON + '9': SOUTH_EAST + '10': SOUTH_WEST + '11': WALES + '12': SCOTLAND + '13': NORTHERN_IRELAND + status_group: + '1': EMPLOYEE + '2': SELF_EMPLOYED + '16': RETIRED + '24': RETIRED + other_status_group: OTHER + sections: + - A + - B + - C + - D + - E + - F + - G + - H + - I + - J + - K + - L + - M + - 'N' + - O + - P + - Q + - R + - S + - T + - U + - kind: impute_soc2020_sub_major_group + output: soc2020_sub_major_group + within: soc2020_major_group + rows: people_with_a_major_group + identity: person_source_id_or_spi_recipient_person_id + seed: 0 + predictors: + - age + - gender + - region + - status_group + - employment_income + - sic_section + categorical_predictors: + - gender + - region + - status_group + - sic_section + unseen_categories: ignore + arcsinh_columns: + - employment_income + arcsinh_scale: 1000.0 + boosted: + learning_rate: 0.05 + max_leaf_nodes: 15 + min_samples_leaf: 40 + l2_regularization: 1.0 + early_stopping: true + validation_fraction: 0.2 + n_iter_no_change: 20 + max_iter: 500 + logit: + n_knots: 6 + degree: 3 + knots: quantile + extrapolation: constant + penalty_c: 1.0 + solver: lbfgs + max_iter: 3000 + boosted_weight: 0.5 + evidence: + folds: 5 + grouping: person + pay_band_quantiles: + - 0.5 + - 0.8 + - 0.9 + age_band_edges: + - 25 + - 35 + - 45 + - 55 + - 65 + outputs: + - soc2020_sub_major_group + notes: 'Runs after spi_employment_shell, which settles every row''s SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job''s for people in employment (ILODEFR 1), the last job''s otherwise, as the FRS records the main or last job. An employee''s pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay (weekly pay times 52, arcsinh in the logit) and SIC 2007 section, the predictors both surveys record alike; a section the group''s donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS''s own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin''s group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds'' class shares; each group''s calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows'' expected sub-major shares against the donors'' within each major group, with counts banded by the shared disclosure rules.' - stage: spi_housing_shell survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 base households' housing (tenure, dwelling type, bedrooms, council tax, housing costs and the housing-linked benefit reports), imputed onto the SPI support households from their own region, composition and post-SPI incomes. diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py new file mode 100644 index 0000000000..26cb35b27b --- /dev/null +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py @@ -0,0 +1,810 @@ +"""Impute each person's SOC 2020 sub-major group within their major group, from the APS. + +The FRS codes an occupation to the major group only, and the SPI employment +shell redraws that group on the SPI-drawn rows. The Annual Population Survey +codes the minor group of the main job, and of the last job for people not in +work, so its adults are the donors for the sub-major group: the minor group's +first two digits. Each major group gets its own model over its sub-major +groups, ``microcosm.fit``'s categorical classifier (the equal mixture of a +regularised boosted classifier and a spline logit) on age, sex, region, +employment-status group, annual pay and SIC 2007 section, the predictors both +surveys record alike. A person with no major group keeps NONE. + +The donors are the APS adults with a minor group whose pay is known: an +employee's pay is asked in the income waves only, so an employee with pay +stands for all employees through the income weight, and everyone else carries +the person weight. The held-out evidence deals five stratified folds by person, +since the End User Licence file carries no household identifier. + +Draws read uniforms keyed on ``person_source_id``, so a copy whose predictors +are its FRS twin's draws its twin's group, except for the SPI income +recipients, whose incomes and occupation the SPI stages drew: they key on +their own ``person_id`` under a salt of their own. +""" + +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.stochastic_assignment import ( + integer_record_keys, + stable_identity_uniforms, +) +from microcosm.build.uk_runtime.occupation_constants import ( + UK_OCCUPATION_STATUS_GROUP, + UK_SIC2007_SECTION_DIVISIONS, + UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP, + UK_SOC2020_MAJOR_GROUPS, + UK_SOC2020_NO_OCCUPATION, + UK_SOC2020_SUB_MAJOR_GROUPS, + uk_sic2007_sections, +) +from microcosm.build.uk_runtime.receipt_counts import ( + UK_DISCLOSURE_FLOOR, + distinct_count, + rounded_count, + small_cell_share, + source_household_ids, + support_band, +) +from microcosm.fit import ( + BoostedClassifierSettings, + CategoricalClassifier, + SplineLogitSettings, + can_deal_folds, + categorical_scores, + out_of_fold_proba, + stratified_folds, +) + +__all__ = [ + "CLEAN_APS_OCCUPATION_TABLE_KIND", + "IMPUTE_SOC2020_SUB_MAJOR_GROUP_KIND", + "UK_APS_OCCUPATION_CLEANING", + "UK_APS_OCCUPATION_IMPUTATION", + "UK_APS_OCCUPATION_OUTPUT", + "UK_APS_OCCUPATION_STAGE_NAME", + "UK_APS_PERSON_TAB_ROLE", + "UKAPSOccupationStageTransform", + "clean_aps_occupation_table", + "impute_soc2020_sub_major_group", + "sub_major_model", +] + +UK_APS_OCCUPATION_STAGE_NAME = "aps_occupation" +UK_APS_PERSON_TAB_ROLE = "aps_person_tab" +CLEAN_APS_OCCUPATION_TABLE_KIND = "clean_aps_occupation_table" +IMPUTE_SOC2020_SUB_MAJOR_GROUP_KIND = "impute_soc2020_sub_major_group" +UK_APS_OCCUPATION_OUTPUT = "soc2020_sub_major_group" +MAJOR_GROUP_COLUMN = "soc2020_major_group" +STATUS_GROUP = "status_group" +SECTION = "sic_section" +PAY = "employment_income" +PREDICTORS = ("age", "gender", "region", STATUS_GROUP, PAY, SECTION) +CATEGORICAL_PREDICTORS = ("gender", "region", STATUS_GROUP, SECTION) +FRS_CHANNEL = "frs" +#: The stratum names the evidence pools share gaps over. +STRATA = ("pay_band", "region", "age_band", "status_group") + +#: The manifest's cleaning operation, mirrored here and checked at stage time. +UK_APS_OCCUPATION_CLEANING: dict[str, Any] = { + "lowercase_columns": True, + "adult_age": 16, + "age_cap": 80, + "pay_weeks": 52, + "columns": { + "age": "AGE", + "sex": "SEX", + "region": "GOVTOF", + "economic_activity": "ILODEFR", + "status": "INECAC05", + "main_minor_group": "SC20MMN", + "last_minor_group": "SC20LMN", + "weekly_pay": "GRSSWK", + "person_weight": "PWTA22", + "income_weight": "PIWTA22", + "main_section": "INDS07M", + "last_section": "INDS07L", + }, + "codes": { + "in_employment": 1, + "under_16": 26, + "employee": 1, + "sex": {"1": "MALE", "2": "FEMALE"}, + "region": { + "1": "NORTH_EAST", + "2": "NORTH_WEST", + "3": "NORTH_WEST", + "4": "YORKSHIRE", + "5": "EAST_MIDLANDS", + "6": "WEST_MIDLANDS", + "7": "EAST_OF_ENGLAND", + "8": "LONDON", + "9": "SOUTH_EAST", + "10": "SOUTH_WEST", + "11": "WALES", + "12": "SCOTLAND", + "13": "NORTHERN_IRELAND", + }, + "status_group": { + "1": "EMPLOYEE", + "2": "SELF_EMPLOYED", + "16": "RETIRED", + "24": "RETIRED", + }, + "other_status_group": "OTHER", + "sections": list(UK_SIC2007_SECTION_DIVISIONS), + }, +} + +#: The manifest's imputation operation, mirrored here and checked at stage time. +UK_APS_OCCUPATION_IMPUTATION: dict[str, Any] = { + "output": UK_APS_OCCUPATION_OUTPUT, + "within": MAJOR_GROUP_COLUMN, + "rows": "people_with_a_major_group", + "identity": "person_source_id_or_spi_recipient_person_id", + "seed": 0, + "predictors": list(PREDICTORS), + "categorical_predictors": list(CATEGORICAL_PREDICTORS), + "unseen_categories": "ignore", + "arcsinh_columns": [PAY], + "arcsinh_scale": 1000.0, + "boosted": { + "learning_rate": 0.05, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "l2_regularization": 1.0, + "early_stopping": True, + "validation_fraction": 0.2, + "n_iter_no_change": 20, + "max_iter": 500, + }, + "logit": { + "n_knots": 6, + "degree": 3, + "knots": "quantile", + "extrapolation": "constant", + "penalty_c": 1.0, + "solver": "lbfgs", + "max_iter": 3000, + }, + "boosted_weight": 0.5, + "evidence": { + "folds": 5, + "grouping": "person", + "pay_band_quantiles": [0.5, 0.8, 0.9], + "age_band_edges": [25, 35, 45, 55, 65], + }, +} + + +def _plain(value: object) -> object: + """A declaration as plain dicts and lists, for an exact comparison.""" + if isinstance(value, Mapping): + return {str(key): _plain(item) for key, item in value.items()} + if isinstance(value, list | tuple): + return [_plain(item) for item in value] + return value + + +def _coded(values: pd.Series, codes: Mapping[str, str]) -> np.ndarray: + """Each numeric code's label from a string-keyed codebook map; None elsewhere.""" + numeric = pd.to_numeric(values, errors="coerce").to_numpy(dtype=np.float64) + out = np.full(len(numeric), None, dtype=object) + for code, label in codes.items(): + out[numeric == float(code)] = label + return out + + +def clean_aps_occupation_table( + raw: pd.DataFrame, cleaning: Mapping[str, Any] = UK_APS_OCCUPATION_CLEANING +) -> tuple[pd.DataFrame, dict[str, Any]]: + """The APS donors in the frame's codings, with a receipt of who left and why. + + A donor is an adult aged ``adult_age`` or over (``under_16`` status + excluded) with a minor group: the main job's when in employment, the last + job's otherwise. An employee needs a weekly pay of zero or more to stay, + since the income weight carries the employees asked; annual pay is the + weekly pay times ``pay_weeks`` where one is recorded and zero elsewhere. + Region, sex and status follow the declared codes, section codes 1 to 21 + are the SIC 2007 sections in order, and anything else is "" (no section). + Ages are capped at ``age_cap``, as the frame's are. + """ + + columns = {key: str(value) for key, value in cleaning["columns"].items()} + table = raw.copy() + if cleaning["lowercase_columns"]: + table.columns = [str(column).lower() for column in table.columns] + columns = {key: value.lower() for key, value in columns.items()} + missing = sorted(set(columns.values()) - set(table.columns)) + if missing: + raise ValueError(f"The APS table lacks the declared columns {missing}.") + codes = cleaning["codes"] + + def number(key: str) -> np.ndarray: + return pd.to_numeric(table[columns[key]], errors="coerce").to_numpy( + dtype=np.float64 + ) + + age = number("age") + status = number("status") + employed = number("economic_activity") == float(codes["in_employment"]) + main_minor = number("main_minor_group") + last_minor = number("last_minor_group") + minor = np.where(employed, main_minor, last_minor) + section_code = np.where(employed, number("main_section"), number("last_section")) + pay = number("weekly_pay") + employee = status == float(codes["employee"]) + region = _coded(table[columns["region"]], codes["region"]) + sex = _coded(table[columns["sex"]], codes["sex"]) + sub_major = np.full(len(table), None, dtype=object) + coded = np.isfinite(minor) & (minor > 0) + sub_major[coded] = ( + pd.Series(minor[coded] // 10) + .astype(np.int64) + .map(UK_SOC2020_SUB_MAJOR_GROUPS) + .to_numpy(dtype=object) + ) + + adult = (age >= float(cleaning["adult_age"])) & (status != float(codes["under_16"])) + with_code = adult & coded + unmapped = with_code & pd.isna(sub_major) + if unmapped.any(): + bad = sorted({int(code) for code in minor[unmapped]}) + raise ValueError( + f"The APS carries SOC 2020 minor group codes {bad} outside the " + "sub-major groups; map them from the release's data dictionary." + ) + weight = np.where(employee, number("income_weight"), number("person_weight")) + # Each adult with a code leaves for the first reason that applies. + no_region = with_code & pd.isna(region) + no_sex = with_code & ~no_region & pd.isna(sex) + pay_unknown = with_code & ~no_region & ~no_sex & employee & ~(pay >= 0) + no_weight = with_code & ~no_region & ~no_sex & ~pay_unknown & ~(weight > 0) + keep = with_code & ~(no_region | no_sex | pay_unknown | no_weight) + + sections = np.asarray(codes["sections"], dtype=object) + in_range = np.isfinite(section_code) & (section_code >= 1) + in_range &= section_code <= len(sections) + section = np.full(len(table), "", dtype=object) + section[in_range] = sections[section_code[in_range].astype(np.int64) - 1] + status_group = _coded(table[columns["status"]], codes["status_group"]) + status_group[pd.isna(status_group)] = codes["other_status_group"] + donors = pd.DataFrame( + { + "age": np.minimum(age, float(cleaning["age_cap"]))[keep], + "gender": sex[keep], + "region": region[keep], + STATUS_GROUP: status_group[keep], + PAY: np.where(pay >= 0, pay * float(cleaning["pay_weeks"]), 0.0)[keep], + SECTION: section[keep], + MAJOR_GROUP_COLUMN: np.asarray( + [UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP[g] for g in sub_major[keep]], + dtype=object, + ), + UK_APS_OCCUPATION_OUTPUT: sub_major[keep], + "weight": weight[keep], + } + ) + receipt = { + "people": rounded_count(len(table)), + "adults_with_a_minor_group": rounded_count(int(with_code.sum())), + "donors": rounded_count(int(keep.sum())), + "dropped": { + "no_region": rounded_count(int(no_region.sum())), + "no_sex": rounded_count(int(no_sex.sum())), + "employee_pay_unknown": rounded_count(int(pay_unknown.sum())), + "no_weight": rounded_count(int(no_weight.sum())), + }, + } + return donors, receipt + + +def sub_major_model( + imputation: Mapping[str, Any], *, boosted_max_iter: int | None = None +) -> CategoricalClassifier: + """The declared classifier. + + ``boosted_max_iter`` caps the boosted learner on a small fixture and turns + its early stopping off there, as the employment shell's does. + """ + boosted = dict(imputation["boosted"]) + if boosted_max_iter is not None: + boosted["max_iter"] = int(boosted_max_iter) + boosted["early_stopping"] = False + return CategoricalClassifier( + boosted_weight=float(imputation["boosted_weight"]), + boosted=BoostedClassifierSettings(**boosted), + logit=SplineLogitSettings(**dict(imputation["logit"])), + categorical_predictors=tuple(imputation["categorical_predictors"]), + arcsinh_scales={ + column: float(imputation["arcsinh_scale"]) + for column in imputation["arcsinh_columns"] + }, + seed=int(imputation["seed"]), + unseen_categories=str(imputation["unseen_categories"]), + ) + + +def _frame_table( + person: pd.DataFrame, household: pd.DataFrame, age_cap: float +) -> pd.DataFrame: + """Every person's predictors, major group, identities and channel.""" + households = household.set_index("household_id") + by_person = person["person_household_id"].to_numpy() + return pd.DataFrame( + { + "person_id": person["person_id"].to_numpy(), + "person_source_id": person["person_source_id"].to_numpy(), + "household_id": by_person, + "age": np.minimum(person["age"].to_numpy(dtype=np.float64), age_cap), + "gender": person["gender"].astype(str).to_numpy(), + "region": households["region"].astype(str).reindex(by_person).to_numpy(), + STATUS_GROUP: person["employment_status"] + .astype(str) + .map(UK_OCCUPATION_STATUS_GROUP) + .to_numpy(dtype=object), + PAY: person[PAY].to_numpy(dtype=np.float64), + SECTION: uk_sic2007_sections(person["sic_industry_division"].to_numpy()), + MAJOR_GROUP_COLUMN: person[MAJOR_GROUP_COLUMN].astype(str).to_numpy(), + "spi_income_recipient": person["person_is_spi_income_recipient"] + .astype(bool) + .to_numpy(), + "channel": households["household_support_channel"] + .astype(str) + .reindex(by_person) + .to_numpy(), + }, + index=person.index, + ) + + +def _keyed_uniforms(table: pd.DataFrame, seed: int) -> np.ndarray: + """One uniform per row: the source person's, or a recipient's own. + + A copy shares its FRS twin's ``person_source_id``, so the twin's uniform is + drawn once and given to every copy; an SPI income recipient keys on its own + ``person_id`` under the recipients' salt. + """ + stage = UK_APS_OCCUPATION_STAGE_NAME + salt = f"{stage}:{UK_APS_OCCUPATION_OUTPUT}" + recipient = table["spi_income_recipient"].to_numpy() + uniforms = np.empty(len(table), dtype=np.float64) + sources = table["person_source_id"].to_numpy()[~recipient] + if len(sources): + unique, inverse = np.unique(sources, return_inverse=True) + keys = integer_record_keys(unique, label=f"{stage} person_source_id") + uniforms[~recipient] = stable_identity_uniforms(keys, seed=seed, salt=salt)[ + inverse + ] + if recipient.any(): + keys = integer_record_keys( + table["person_id"].to_numpy()[recipient], label=f"{stage} person_id" + ) + uniforms[recipient] = stable_identity_uniforms( + keys, seed=seed, salt=f"{salt}:spi_income_recipient" + ) + return uniforms + + +def _pay_bands( + pay: np.ndarray, weights: np.ndarray, quantiles: Sequence[float] +) -> np.ndarray: + """No pay, then bands at the weighted quantiles of positive pay.""" + band = np.zeros(len(pay), dtype=np.int64) + positive = pay > 0 + if positive.any(): + order = np.argsort(pay[positive], kind="stable") + cumulative = np.cumsum(weights[positive][order]) + cuts = np.interp(quantiles, cumulative / cumulative[-1], pay[positive][order]) + band[positive] = np.digitize(pay[positive], cuts) + 1 + return band + + +def _weighted_shares( + values: np.ndarray, weights: np.ndarray, sources: np.ndarray +) -> dict[str, object]: + """Each value's weighted share, withheld where one or two households carry it.""" + total = weights.sum() + out: dict[str, object] = {} + for value in np.unique(values): + rows = values == value + out[str(value)] = small_cell_share( + float(weights[rows].sum() / total), distinct_count(sources, rows) + ) + return out + + +def _held_out_group( + model: CategoricalClassifier, + donors: pd.DataFrame, + folds: np.ndarray, + evidence: Mapping[str, Any], +) -> tuple[dict[str, dict[str, object]], float]: + """One major group's out-of-fold scores for the model, its learners and the constant.""" + weights = donors["weight"].to_numpy(dtype=np.float64) + out = out_of_fold_proba( + model, + donors, + list(PREDICTORS), + UK_APS_OCCUPATION_OUTPUT, + weights=weights, + folds=folds, + ) + strata = { + "pay_band": _pay_bands( + donors[PAY].to_numpy(), weights, list(evidence["pay_band_quantiles"]) + ), + "region": donors["region"].to_numpy(), + "age_band": np.digitize( + donors["age"].to_numpy(), list(evidence["age_band_edges"]) + ), + "status_group": donors[STATUS_GROUP].to_numpy(), + } + labels = donors[UK_APS_OCCUPATION_OUTPUT].to_numpy() + scores = { + name: categorical_scores( + out[name], labels, out["classes"], weights, strata=strata + ) + for name in ("model", "boosted", "spline_logit", "marginal") + if name in out + } + return scores, float(weights.sum()) + + +def _pooled_evidence( + groups: Mapping[str, tuple[dict[str, dict[str, object]], float]], + support: Mapping[str, int], +) -> dict[str, object]: + """Log losses and share gaps pooled over the major groups, weight-weighted. + + A learner is pooled only where every group fitted it: a group with one + sub-major group among its donors fits neither learner. + """ + total = sum(weight for _, weight in groups.values()) + learners = [ + name + for name in ("model", "boosted", "spline_logit", "marginal") + if all(name in scores for scores, _ in groups.values()) + ] + log_loss = { + name: sum( + weight * float(scores[name]["log_loss"]) + for scores, weight in groups.values() + ) + / total + for name in learners + } + gaps: dict[str, float] = {} + for stratum in STRATA: + weighted = weight_total = 0.0 + for scores, _ in groups.values(): + for level in scores["model"]["strata"][stratum].values(): + weighted += float(level["weight"]) * float(level["share_gap"]) + weight_total += float(level["weight"]) + gaps[f"{stratum}_share_gap"] = weighted / weight_total + per_group: dict[str, object] = {} + for group, (scores, _) in groups.items(): + model = scores["model"] + per_group[group] = { + "support": support_band(support[group]), + "log_loss": { + name: float(value["log_loss"]) for name, value in scores.items() + }, + "calibration_slope": model["calibration_slope"], + "calibration_outcome": model["calibration_outcome"], + } + return { + "status": "measured", + "log_loss": log_loss, + **gaps, + "major_groups": per_group, + } + + +def impute_soc2020_sub_major_group( + person: pd.DataFrame, + household: pd.DataFrame, + household_weights: np.ndarray, + donors: pd.DataFrame, + *, + imputation: Mapping[str, Any] = UK_APS_OCCUPATION_IMPUTATION, + age_cap: float = float(UK_APS_OCCUPATION_CLEANING["age_cap"]), + boosted_max_iter: int | None = None, +) -> tuple[pd.DataFrame, dict[str, Any], tuple[FitWeightRecord, ...]]: + """Draw every person's sub-major group within their major group; NONE stays NONE.""" + + stage = UK_APS_OCCUPATION_STAGE_NAME + if UK_APS_OCCUPATION_OUTPUT in person.columns: + raise ValueError( + f"{stage}: the frame already carries {UK_APS_OCCUPATION_OUTPUT}." + ) + table = _frame_table(person, household, age_cap) + weight_by_household = pd.Series( + np.asarray(household_weights, dtype=np.float64), + index=household["household_id"].to_numpy(), + ) + weights = weight_by_household.reindex(table["household_id"]).to_numpy() + source_by_household = pd.Series( + source_household_ids(household, stage=stage), + index=household["household_id"].to_numpy(), + ) + sources = source_by_household.reindex(table["household_id"]).to_numpy() + majors = table[MAJOR_GROUP_COLUMN].to_numpy() + unknown = sorted( + set(majors) - {UK_SOC2020_NO_OCCUPATION, *UK_SOC2020_MAJOR_GROUPS.values()} + ) + if unknown: + raise ValueError(f"{stage}: major groups {unknown} are not SOC 2020's.") + coded = majors != UK_SOC2020_NO_OCCUPATION + unmapped = coded & pd.isna(table[STATUS_GROUP]).to_numpy() + if unmapped.any(): + statuses = sorted(set(person.loc[unmapped, "employment_status"].astype(str))) + raise ValueError( + f"{stage}: people with a major group hold employment statuses " + f"{statuses} that have no occupation status group." + ) + + seed = int(imputation["seed"]) + evidence = imputation["evidence"] + fold_count = int(evidence["folds"]) + model = sub_major_model(imputation, boosted_max_iter=boosted_max_iter) + uniforms = _keyed_uniforms(table, seed) + drawn = np.full(len(table), UK_SOC2020_NO_OCCUPATION, dtype=object) + frs_rows = (table["channel"].to_numpy() == FRS_CHANNEL) & (weights > 0) + records: list[FitWeightRecord] = [] + held_out: dict[str, tuple[dict[str, dict[str, object]], float]] = {} + not_measured: list[str] = [] + fits: dict[str, object] = {} + donor_support: dict[str, int] = {} + frame_gaps: dict[str, object] = {} + frame_gap_values: list[float] = [] + shares: dict[str, dict[str, object]] = {"donors": {}, "frame": {}} + unseen = np.zeros(len(table), dtype=bool) + for code, group in UK_SOC2020_MAJOR_GROUPS.items(): + group_donors = donors.loc[donors[MAJOR_GROUP_COLUMN] == group].reset_index( + drop=True + ) + if group_donors.empty: + raise ValueError(f"{stage}: the APS has no donors in major group {group}.") + donor_support[group] = len(group_donors) + donor_weights = group_donors["weight"].to_numpy(dtype=np.float64) + labels = group_donors[UK_APS_OCCUPATION_OUTPUT].to_numpy() + if can_deal_folds(labels, fold_count): + folds = stratified_folds( + labels, + fold_count, + np.random.default_rng(np.random.SeedSequence([seed, code])), + ) + held_out[group] = _held_out_group(model, group_donors, folds, evidence) + else: + not_measured.append(group) + fitted = model.fit( + group_donors, + list(PREDICTORS), + [UK_APS_OCCUPATION_OUTPUT], + weights=donor_weights, + ) + records.append( + FitWeightRecord( + f"{stage}:{UK_APS_OCCUPATION_OUTPUT}:{group}", fitted.weight_kind + ) + ) + fits[group] = fitted.diagnostics + donor_shares = ( + pd.Series(donor_weights).groupby(labels).sum() / donor_weights.sum() + ) + shares["donors"][group] = { + str(name): small_cell_share(float(value), int((labels == name).sum())) + for name, value in donor_shares.items() + } + rows = majors == group + if not rows.any(): + continue + group_table = table.loc[rows] + unseen[rows] = fitted.unseen_category_rows(group_table) + drawn[rows] = fitted.predict_from_uniforms(group_table, uniforms[rows])[ + UK_APS_OCCUPATION_OUTPUT + ].to_numpy() + frame = rows & frs_rows + if not frame.any(): + continue + # The FRS rows' expected shares against the donors': how far the + # FRS's predictor mix within the group moves the draw from the APS. + households = distinct_count(sources, frame) + expected = ( + weights[frame] + @ fitted.predict_proba(table.loc[frame]) + / weights[frame].sum() + ) + observed = donor_shares.reindex(fitted.classes_, fill_value=0.0).to_numpy() + gap = float(0.5 * np.abs(expected - observed).sum()) + frame_gaps[group] = { + "support": support_band(households), + "share_gap": small_cell_share(gap, households), + } + if households >= UK_DISCLOSURE_FLOOR: + frame_gap_values.append(gap) + shares["frame"][group] = _weighted_shares( + drawn[frame], weights[frame], sources[frame] + ) + + if not_measured: + held_out_evidence: dict[str, object] = { + "status": "not_measured", + "reason": "a sub-major group has fewer donors than folds", + "major_groups_not_measured": not_measured, + "log_loss": None, + } + else: + held_out_evidence = _pooled_evidence(held_out, donor_support) + held_out_evidence.update({"folds": fold_count, "grouping": evidence["grouping"]}) + + person_out = person.copy() + person_out[UK_APS_OCCUPATION_OUTPUT] = drawn + receipt: dict[str, Any] = { + "donors": { + group: rounded_count(count) for group, count in donor_support.items() + }, + "drawn": { + "people": rounded_count(int(coded.sum())), + "source_households": rounded_count(distinct_count(sources, coded)), + "spi_income_recipients": rounded_count( + int((coded & table["spi_income_recipient"].to_numpy()).sum()) + ), + "unseen_category_households": rounded_count( + distinct_count(sources, unseen) + ), + }, + "fit": fits, + "held_out": held_out_evidence, + "frame_against_donors": { + "share_gap_max": max(frame_gap_values) if frame_gap_values else None, + "major_groups": frame_gaps, + }, + "category_shares": shares, + } + return person_out, receipt, tuple(records) + + +def _assert_stage_parameters(stage) -> None: + if stage.stage != UK_APS_OCCUPATION_STAGE_NAME: + raise ValueError( + f"APS occupation received stage {stage.stage!r}, expected " + f"{UK_APS_OCCUPATION_STAGE_NAME!r}." + ) + kinds = [operation.kind for operation in stage.operations] + expected = [CLEAN_APS_OCCUPATION_TABLE_KIND, IMPUTE_SOC2020_SUB_MAJOR_GROUP_KIND] + if kinds != expected: + raise ValueError( + f"aps_occupation operations drifted: expected {expected}, got {kinds}." + ) + for operation, declared in zip( + stage.operations, + (UK_APS_OCCUPATION_CLEANING, UK_APS_OCCUPATION_IMPUTATION), + strict=True, + ): + actual = _plain(dict(operation.parameters)) + if actual != _plain(declared): + raise ValueError( + f"aps_occupation {operation.kind} parameters drifted: expected " + f"{declared}, got {actual}." + ) + if tuple(stage.outputs) != (UK_APS_OCCUPATION_OUTPUT,) or tuple(stage.rewrites): + raise ValueError( + "aps_occupation must declare exactly the output " + f"{UK_APS_OCCUPATION_OUTPUT!r} and no rewrites." + ) + + +def _assert_invariants(person_in: pd.DataFrame, person_out: pd.DataFrame) -> None: + """Only the new column is added, and it nests in each row's major group.""" + if not person_in.equals(person_out.drop(columns=[UK_APS_OCCUPATION_OUTPUT])): + raise ValueError("APS occupation modified a column it does not write.") + majors = person_out[MAJOR_GROUP_COLUMN].astype(str).to_numpy() + nested = ( + person_out[UK_APS_OCCUPATION_OUTPUT] + .map(UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP) + .to_numpy(dtype=object) + ) + if not (nested == majors).all(): + raise ValueError( + "APS occupation drew a sub-major group outside a row's major group." + ) + + +def _artifact(stage, role: str) -> Mapping[str, Any]: + for artifact in stage.artifacts: + if artifact.get("role") == role: + return artifact + raise ValueError(f"{stage.stage} declares no {role!r} artifact.") + + +@dataclass +class UKAPSOccupationStageTransform: + """Whole-stage callable: draw every person's SOC 2020 sub-major group.""" + + stage: Any + aps_tab_path: str | Path | None = None + donor: pd.DataFrame | None = None + boosted_max_iter: int | None = None + last_receipt: dict[str, Any] | None = field(default=None, init=False) + last_fit_weight_records: tuple[FitWeightRecord, ...] | None = field( + default=None, init=False, repr=False + ) + + @property + def fit_weight_records(self) -> tuple[FitWeightRecord, ...]: + return ( + () if self.last_fit_weight_records is None else self.last_fit_weight_records + ) + + def _raw_donor(self) -> pd.DataFrame: + if self.donor is not None: + return self.donor + if self.aps_tab_path is None: + raise ValueError( + f"{UK_APS_OCCUPATION_STAGE_NAME} requires the caller-supplied APS " + "person tab." + ) + from microcosm.build.uk_runtime.frs_spine import read_pinned_tab + + return read_pinned_tab( + Path(self.aps_tab_path).expanduser().resolve(), + _artifact(self.stage, UK_APS_PERSON_TAB_ROLE), + columns=list(UK_APS_OCCUPATION_CLEANING["columns"].values()), + ) + + def __call__(self, frame): + from microcosm.build.uk_runtime.national_frame import ( + uk_household_weight_kind, + uk_national_frame, + uk_time_period, + validate_uk_national_frame, + ) + + _assert_stage_parameters(self.stage) + validate_uk_national_frame(frame) + donors, cleaning_receipt = clean_aps_occupation_table(self._raw_donor()) + person = frame.table("person") + person_out, receipt, records = impute_soc2020_sub_major_group( + person, + frame.table("household"), + np.asarray(frame.weights_for("household").values, dtype=float), + donors, + boosted_max_iter=self.boosted_max_iter, + ) + _assert_invariants(person, person_out) + result = uk_national_frame( + person=person_out, + benunit=frame.table("benunit").copy(), + household=frame.table("household").copy(), + time_period=uk_time_period(frame), + weight_kind=uk_household_weight_kind(frame), + household_weights=frame.weights_for("household").values, + mass_log=frame.mass_log, + ) + validate_uk_national_frame(result) + self.last_fit_weight_records = records + self.last_receipt = { + "stage": UK_APS_OCCUPATION_STAGE_NAME, + "donor_table": cleaning_receipt, + **receipt, + } + return result + + @staticmethod + def output_columns() -> tuple[str, ...]: + return (UK_APS_OCCUPATION_OUTPUT,) + + def checkpoint_metadata(self) -> dict[str, object]: + if self.last_receipt is None: + raise RuntimeError("checkpoint metadata requires a completed stage run.") + return {"evidence": self.last_receipt} 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 aa5085a375..d8a28f2910 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 @@ -2202,6 +2202,11 @@ def _ledger_compile_parity_required_artifacts( "maximum_pay_band_share_gap", "maximum_status_group_share_gap", "maximum_blend_log_loss_excess", + # The sub_major_draw check (microcosm#1490) shares those and adds + # the sub-major share gap within regions and the FRS rows' gap + # from the APS donors within a major group. + "maximum_region_share_gap", + "maximum_frame_share_gap", # #1113 road_fuel_incidence check: the ceiling on the chain's # zero share among flagged fuel-car households. "maximum_flagged_zero_share", 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 7656494931..f565ae64de 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 @@ -159,6 +159,7 @@ "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", "uk_stage_spi_employment_shell_fit", + "uk_stage_aps_occupation_fit", # Weight-independent like the BRMA enum below, and its column exists from # frs_relationships onward (#791). "uk_ons_household_type_enum_domain", @@ -196,6 +197,7 @@ "uk_take_up_signal", "uk_student_loan_plan_enum_domain", "uk_soc2020_major_group_enum_domain", + "uk_soc2020_sub_major_group_enum_domain", # The spine checks council_tax_band at the transferred boundary; this # instance checks the release frame, after any later step that writes the # band (microcosm#1278). 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 6372946355..0ab5d23ce4 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -209,6 +209,7 @@ ), "etb_vat": ("etb",), "etb_services": ("etb",), + "aps_occupation": ("aps",), "frs_hmrc_spine_leaves": ("frs",), "frs_annual_income_spells": ("frs",), "spi_income_band_donors": ("spi",), @@ -228,6 +229,7 @@ "lcfs_household": "Pinned local LCFS household donor table.", "lcfs_person": "Pinned local LCFS person donor table.", "etb": "Pinned local ETB household donor table.", + "aps": "Pinned local APS person donor table.", "spi": "Pinned local SPI donor table.", "hmrc_income": "Pinned local HMRC income facts workbook.", } @@ -405,6 +407,23 @@ ("household", "household_source_id"), } ), + # Engine-free: the sub-major predictors, the major group it nests in, the + # draw keys and the channel split (microcosm#1490). + "aps_occupation": frozenset( + { + ("person", "age"), + ("person", "gender"), + ("person", "employment_status"), + ("person", "employment_income"), + ("person", "sic_industry_division"), + ("person", "soc2020_major_group"), + ("person", "person_is_spi_income_recipient"), + ("person", "person_source_id"), + ("household", "region"), + ("household", "household_support_channel"), + ("household", "household_source_id"), + } + ), # Engine-free: the housing predictors and the channel split. The rewritten # housing and benefit cells arrive as the rewrite's incumbents. "spi_housing_shell": frozenset( @@ -1178,6 +1197,7 @@ def _cells( _Cell("person", "sic_industry_division", "int64"), _Cell("person", "employment_sector", "string"), ), + "aps_occupation": (_Cell("person", "soc2020_sub_major_group", "string"),), "spi_housing_shell": ( *_cells( "household", 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 7989108665..0745858168 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 @@ -121,6 +121,7 @@ "spi_income_band_donors": "spi_band_donors", "hmrc_spi_income_spine": "spi_spine", "spi_employment_shell": "spi_employment_shell", + "aps_occupation": "aps_occupation", "spi_housing_shell": "spi_housing_shell", "uc_reporter_redraw": "uc_reporter_redraw", "spi_benefit_coherence": "spi_benefit_coherence", @@ -281,6 +282,17 @@ receipt_counts, stochastic_assignment, ), + # The sub-major draw fits and scores through microcosm.fit's categorical + # classifier and held-out scores, reads the shared occupation codes, and + # counts its receipt's support by the shared disclosure rules + # (microcosm#1490). + "aps_occupation": ( + fit_categorical, + fit_held_out, + occupation_constants, + receipt_counts, + stochastic_assignment, + ), } _COMPUTE = Capabilities( @@ -580,6 +592,7 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: from microcosm.frame.adapters.policyengine_uk import PolicyEngineUKEngine from .age_tail import UKAgeTailStageTransform + from .aps_occupation import UKAPSOccupationStageTransform from .carers_allowance_take_up import UKCarersAllowanceTakeUpStageTransform from .cgt_asset_type import UKCGTAssetTypeStageTransform, UKCGTBADRParameters from .cgt_imputation import UKCGTPolicyParameters, uk_cgt_spine_stage_transform @@ -662,6 +675,9 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: etb = pd.read_csv( _fixture_input(source, inputs, "etb"), float_precision="round_trip" ) + aps = pd.read_csv( + _fixture_input(source, inputs, "aps"), float_precision="round_trip" + ) nts_household = pd.read_csv( _fixture_input(source, inputs, "nts_household"), float_precision="round_trip" ) @@ -828,6 +844,11 @@ def _fixture_implementations(source: Path) -> Mapping[str, object]: "spi_employment_shell": UKSPIEmploymentShellStageTransform( stage=stages["spi_employment_shell"], boosted_max_iter=qrf_estimators ), + "aps_occupation": UKAPSOccupationStageTransform( + stage=stages["aps_occupation"], + donor=aps, + boosted_max_iter=qrf_estimators, + ), "spi_housing_shell": UKSPIHousingShellStageTransform( stage=stages["spi_housing_shell"], n_estimators=qrf_estimators ), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py index 8bef7fd60b..4195a8cd5a 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/occupation_constants.py @@ -28,6 +28,52 @@ } ) +#: The engine's ``soc2020_sub_major_group`` members (policyengine-uk +#: ``SOC2020SubMajorGroup``) by SOC 2020 sub-major group code, in code order +#: (ONS SOC 2020 Volume 1). A sub-major group's first digit is its major group. +UK_SOC2020_SUB_MAJOR_GROUPS: Mapping[int, str] = MappingProxyType( + { + 11: "CORPORATE_MANAGERS_AND_DIRECTORS", + 12: "OTHER_MANAGERS_AND_PROPRIETORS", + 21: "SCIENCE_RESEARCH_ENGINEERING_AND_TECHNOLOGY_PROFESSIONALS", + 22: "HEALTH_PROFESSIONALS", + 23: "TEACHING_AND_OTHER_EDUCATIONAL_PROFESSIONALS", + 24: "BUSINESS_MEDIA_AND_PUBLIC_SERVICE_PROFESSIONALS", + 31: "SCIENCE_ENGINEERING_AND_TECHNOLOGY_ASSOCIATE_PROFESSIONALS", + 32: "HEALTH_AND_SOCIAL_CARE_ASSOCIATE_PROFESSIONALS", + 33: "PROTECTIVE_SERVICE", + 34: "CULTURE_MEDIA_AND_SPORTS", + 35: "BUSINESS_AND_PUBLIC_SERVICE_ASSOCIATE_PROFESSIONALS", + 41: "ADMINISTRATIVE", + 42: "SECRETARIAL_AND_RELATED", + 51: "SKILLED_AGRICULTURAL_AND_RELATED_TRADES", + 52: "SKILLED_METAL_ELECTRICAL_AND_ELECTRONIC_TRADES", + 53: "SKILLED_CONSTRUCTION_AND_BUILDING_TRADES", + 54: "TEXTILES_PRINTING_AND_OTHER_SKILLED_TRADES", + 61: "CARING_PERSONAL_SERVICE", + 62: "LEISURE_TRAVEL_AND_RELATED_PERSONAL_SERVICE", + 63: "COMMUNITY_AND_CIVIL_ENFORCEMENT", + 71: "SALES", + 72: "CUSTOMER_SERVICE", + 81: "PROCESS_PLANT_AND_MACHINE_OPERATIVES", + 82: "TRANSPORT_AND_MOBILE_MACHINE_DRIVERS_AND_OPERATIVES", + 91: "ELEMENTARY_TRADES_AND_RELATED", + 92: "ELEMENTARY_ADMINISTRATION_AND_SERVICE", + } +) + +#: Each sub-major group's major group, by member name, derived from the codes; +#: NONE is its own. +UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP: Mapping[str, str] = MappingProxyType( + { + UK_SOC2020_NO_OCCUPATION: UK_SOC2020_NO_OCCUPATION, + **{ + name: UK_SOC2020_MAJOR_GROUPS[code // 10] + for code, name in UK_SOC2020_SUB_MAJOR_GROUPS.items() + }, + } +) + #: The FRS adult-table ``SOC2020`` coding -> the engine's member: 0 is undefined, #: and each major group is its code times 1000 (UKDS FRS 2024-25 data #: dictionary, SN 9563). @@ -102,6 +148,8 @@ def uk_sic2007_sections(divisions) -> np.ndarray: "UK_OCCUPATION_STATUS_GROUP", "UK_SIC2007_SECTION_DIVISIONS", "UK_SOC2020_MAJOR_GROUPS", + "UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP", "UK_SOC2020_NO_OCCUPATION", + "UK_SOC2020_SUB_MAJOR_GROUPS", "uk_sic2007_sections", ] diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/receipt_counts.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/receipt_counts.py index f409be5e3a..a886c6ae64 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/receipt_counts.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/receipt_counts.py @@ -18,11 +18,13 @@ higher floor. The UK Data Service catalogue entries were read for conditions beyond the End User Licence (microcosm#1278): the FRS 2024-25 (SN 9563) has none (checked 2026-10-16), and neither have the LCFS, ETB, WAS and NTS studies -(checked 2026-10-14). The SPI 2022-23 Public Use Tape (SN 9422, checked -2026-10-16) adds two: no attempt may be made to attribute a record to a named -individual, and material that includes analyses of the tape goes to HMRC at -least ten working days before it is distributed or published. The move to -three changes neither. The build marks the outputs that rest on the tape +(checked 2026-10-14) or the APS, April 2024 - March 2025 (SN 9408, checked +2026-11-04), whose access and copyright terms read as the FRS's. The SPI +2022-23 Public Use Tape (SN 9422, checked 2026-10-16) adds two: no attempt may +be made to attribute a record to a named individual, and material that +includes analyses of the tape goes to HMRC at least ten working days before it +is distributed or published. The move to three changes neither. The build +marks the outputs that rest on the tape (:mod:`microcosm.build.uk_runtime.spi_dependency`). """ diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py index 0e8f462884..86c62c5297 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spine_build.py @@ -67,6 +67,7 @@ ) from microcosm.build.termination import BuildTerminatedError, raise_on_sigterm from microcosm.build.uk_runtime.age_tail import UKAgeTailStageTransform +from microcosm.build.uk_runtime.aps_occupation import UKAPSOccupationStageTransform from microcosm.build.uk_runtime.battery_bindings import UK_GATE_REGISTRY from microcosm.build.uk_runtime.calibration_run import ( UK_SPINE_GATE_SCOPE, @@ -417,6 +418,14 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: type=Path, help="Caller-supplied private ETB 1977-2024 household tab for ETB stages.", ) + parser.add_argument( + "--aps-tab", + type=Path, + help=( + "Caller-supplied private APS April 2024-March 2025 person tab for " + "aps_occupation." + ), + ) parser.add_argument( "--emit-nonzero-shares", type=Path, @@ -465,6 +474,7 @@ def _parse_args(argv: list[str] | None = None) -> argparse.Namespace: ("--lcfs-hh-tab", args.lcfs_hh_tab), ("--lcfs-person-tab", args.lcfs_person_tab), ("--etb-tab", args.etb_tab), + ("--aps-tab", args.aps_tab), ) if value is not None ) @@ -574,6 +584,7 @@ def _synthetic_graph_sources(source: Path) -> dict[str, Path]: "lcfs_household": "lcfs_household", "lcfs_person": "lcfs_person", "etb": "etb", + "aps": "aps", "spi": "spi_donor", "hmrc_income": "hmrc_income_targets", } @@ -1647,6 +1658,12 @@ def prepare_uk_spine_execution( raise ValueError( "--etb-tab is required when etb_vat or etb_services is scheduled." ) + if ( + args.synthetic_fixture_dir is None + and "aps_occupation" in stage_names + and args.aps_tab is None + ): + raise ValueError("--aps-tab is required when aps_occupation is scheduled.") stages = [stages_by_name[name] for name in stage_names] synthetic_fixture = _synthetic_fixture_evidence(args.synthetic_fixture_dir) engine = _rules_engine() @@ -1849,6 +1866,13 @@ def prepare_uk_spine_execution( implementations["spi_employment_shell"] = UKSPIEmploymentShellStageTransform( stage=stages_by_name["spi_employment_shell"] ) + if "aps_occupation" in stage_names: + implementations["aps_occupation"] = _GraphSourceTransform( + lambda sources: UKAPSOccupationStageTransform( + stage=stages_by_name["aps_occupation"], + aps_tab_path=sources["aps"], + ) + ) if "spi_housing_shell" in stage_names: implementations["spi_housing_shell"] = UKSPIHousingShellStageTransform( stage=stages_by_name["spi_housing_shell"] @@ -2029,6 +2053,8 @@ def prepare_uk_spine_execution( graph_sources["nts_vehicle"] = args.nts_vehicle_tab if "etb_vat" in stage_names or "etb_services" in stage_names: graph_sources["etb"] = args.etb_tab + if "aps_occupation" in stage_names: + graph_sources["aps"] = args.aps_tab if "spi_income_band_donors" in stage_names: graph_sources["spi"] = args.spi_tab if "property_components" in stage_names: 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 7316a766d1..c274d42825 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 @@ -126,6 +126,8 @@ def uk_stage_health_gate( return _company_cars_gate(stage, evidence, parameters) if check == "occupation_redraw": return _occupation_redraw_gate(stage, evidence, parameters) + if check == "sub_major_draw": + return _sub_major_draw_gate(stage, evidence, parameters) return GateResult( name="stage_health", passed=False, @@ -5404,3 +5406,134 @@ def _occupation_redraw_gate( failures=tuple(failures), details=details, ) + + +def _sub_major_draw_gate( + stage: str, + evidence: Mapping[str, object], + parameters: Mapping[str, object], +) -> GateResult: + """The APS sub-major draw's held-out and frame evidence (microcosm#1490). + + Fails when the evidence was not measured; when the model's out-of-fold log + loss, pooled over the major groups, is not ``minimum_log_loss_gain`` below + the constant's; when the blend loses more than + ``maximum_blend_log_loss_excess`` to its better learner; when a major + group's calibration slope leaves ``calibration_slope_bounds`` or its Platt + fit fell back to class rates; when the pooled sub-major share gaps exceed + ``maximum_pay_band_share_gap`` within pay bands or + ``maximum_region_share_gap`` within regions; or when the FRS rows' + expected shares miss the donors' in some major group by more than + ``maximum_frame_share_gap``. + """ + + check = "sub_major_draw" + minimum_gain = _finite_number( + parameters["minimum_log_loss_gain"], label=f"{stage}.minimum_log_loss_gain" + ) + low, high = ( + _finite_number(bound, label=f"{stage}.calibration_slope_bounds") + for bound in parameters["calibration_slope_bounds"] + ) + maximum_pay = _finite_number( + parameters["maximum_pay_band_share_gap"], + label=f"{stage}.maximum_pay_band_share_gap", + ) + maximum_region = _finite_number( + parameters["maximum_region_share_gap"], + label=f"{stage}.maximum_region_share_gap", + ) + maximum_excess = _finite_number( + parameters["maximum_blend_log_loss_excess"], + label=f"{stage}.maximum_blend_log_loss_excess", + ) + maximum_frame = _finite_number( + parameters["maximum_frame_share_gap"], + label=f"{stage}.maximum_frame_share_gap", + ) + held_out = _mapping(evidence.get("held_out"), label=f"{stage}.held_out") + details: dict[str, object] = {"stage": stage, "check": check} + if held_out.get("status") != "measured": + return GateResult( + name="stage_health", + passed=False, + failures=( + f"{stage}: the held-out evidence was not measured " + f"({held_out.get('reason')}).", + ), + details=details, + ) + failures: list[str] = [] + losses = _mapping(held_out.get("log_loss"), label=f"{stage}.held_out.log_loss") + model = _finite_number(losses.get("model"), label=f"{stage}.log_loss.model") + constant = _finite_number( + losses.get("marginal"), label=f"{stage}.log_loss.marginal" + ) + if constant - model < minimum_gain: + failures.append( + f"{stage}: the model's pooled log loss ({model:.4f}) is less than " + f"{minimum_gain} below the constant's ({constant:.4f})." + ) + learners = { + name: _finite_number(losses[name], label=f"{stage}.log_loss.{name}") + for name in ("boosted", "spline_logit") + if name in losses + } + if len(learners) == 2 and model > min(learners.values()) + maximum_excess: + failures.append( + f"{stage}: the blend's pooled log loss ({model:.4f}) exceeds its better " + f"learner's ({min(learners.values()):.4f}) by more than {maximum_excess}." + ) + groups = _mapping(held_out.get("major_groups"), label=f"{stage}.major_groups") + slopes: dict[str, object] = {} + for group, entry in groups.items(): + entry = _mapping(entry, label=f"{stage}.major_groups.{group}") + slope = entry.get("calibration_slope") + slopes[str(group)] = slope + if slope is None or entry.get("calibration_outcome") != "cross_fitted": + failures.append( + f"{stage}: the calibration slope of {group} could not be fitted." + ) + continue + value = _finite_number(slope, label=f"{stage}.{group}.calibration_slope") + if not low <= value <= high: + failures.append( + f"{stage}: the calibration slope of {group} ({value:.3f}) is " + f"outside [{low}, {high}]." + ) + for key, maximum, label in ( + ("pay_band_share_gap", maximum_pay, "pay bands"), + ("region_share_gap", maximum_region, "regions"), + ): + gap = _finite_number(held_out.get(key), label=f"{stage}.{key}") + if gap > maximum: + failures.append( + f"{stage}: sub-major shares miss within the {label} by {gap:.4f} " + f"on average, above {maximum}." + ) + frame = _mapping( + evidence.get("frame_against_donors"), label=f"{stage}.frame_against_donors" + ) + frame_gap = frame.get("share_gap_max") + if frame_gap is None: + failures.append(f"{stage}: no major group compares the FRS rows with donors.") + else: + value = _finite_number(frame_gap, label=f"{stage}.frame_share_gap_max") + if value > maximum_frame: + failures.append( + f"{stage}: the FRS rows' expected sub-major shares miss the donors' " + f"by {value:.4f} in a major group, above {maximum_frame}." + ) + details.update( + { + "log_loss": dict(losses), + "calibration_slopes": slopes, + "frame_share_gap_max": frame_gap, + } + ) + return GateResult( + name="stage_health", + passed=not failures, + failures=tuple(failures), + details=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 9a9e435bd4..a23f984c0c 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 @@ -385,6 +385,7 @@ def __post_init__(self) -> None: "person.salary_sacrifice_reported", "person.sic_industry_division", "person.soc2020_major_group", + "person.soc2020_sub_major_group", "person.stands_as_sole_owner_or_partner_of_company", "person.statutory_paternity_pay", "person.student_loan_balance", diff --git a/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py b/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py index e5dc88de35..b9ac1b5413 100644 --- a/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py +++ b/packages/microcosm-build/tests/engine/uk/test_uk_occupation_constants.py @@ -4,10 +4,15 @@ SOC2020_MAJOR_GROUP_CODES, SOC2020MajorGroup, ) +from policyengine_uk.variables.household.income.soc2020_sub_major_group import ( + SOC2020_SUB_MAJOR_GROUP_CODES, + SOC2020SubMajorGroup, +) from microcosm.build.uk_runtime.occupation_constants import ( UK_SOC2020_MAJOR_GROUPS, UK_SOC2020_NO_OCCUPATION, + UK_SOC2020_SUB_MAJOR_GROUPS, ) @@ -21,3 +26,15 @@ def test_major_group_codes_are_the_engine_code_map() -> None: assert dict(SOC2020_MAJOR_GROUP_CODES) == { name: code for code, name in UK_SOC2020_MAJOR_GROUPS.items() } + + +def test_sub_major_groups_are_the_engine_enum_in_code_order() -> None: + members = list(SOC2020SubMajorGroup.__members__) + assert members[0] == UK_SOC2020_NO_OCCUPATION + assert members[1:] == list(UK_SOC2020_SUB_MAJOR_GROUPS.values()) + + +def test_sub_major_group_codes_are_the_engine_code_map() -> None: + assert dict(SOC2020_SUB_MAJOR_GROUP_CODES) == { + name: code for code, name in UK_SOC2020_SUB_MAJOR_GROUPS.items() + } diff --git a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py index e01fe9e92a..bec1dac36b 100644 --- a/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py +++ b/packages/microcosm-build/tests/engine_free/shared/test_country_spec.py @@ -1198,8 +1198,9 @@ def test_uk_source_manifest_contains_only_canonical_spine_stages(self) -> None: # stage; microcosm#1334 uc_take_up after uc_capital_coherence and # frs_annual_income_spells after frs_hmrc_spine_leaves; microcosm#1428 # trading_allowance_receipts last; company_cars right after - # hmrc_spi_income_spine (PolicyEngine/uk-autumn-budget-dashboard-2026#316). - assert len(spec.sources.stages) == 53 + # hmrc_spi_income_spine (PolicyEngine/uk-autumn-budget-dashboard-2026#316); + # microcosm#1490 spi_employment_shell after it and aps_occupation next. + assert len(spec.sources.stages) == 54 assert not {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.intersection( stage.stage for stage in spec.sources.stages ) @@ -1642,6 +1643,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", "uk_stage_spi_employment_shell_fit", + "uk_stage_aps_occupation_fit", "uk_release_input_coverage", "uk_degenerate_release_surface", "uk_zero_weight_strata", @@ -1661,6 +1663,7 @@ def test_declares_the_full_june_battery(self, manifest) -> None: "uk_uc_deduction_combination_enum_domain", "uk_student_loan_plan_enum_domain", "uk_soc2020_major_group_enum_domain", + "uk_soc2020_sub_major_group_enum_domain", "uk_council_tax_band_domain_terminal", "uk_calibration_reference_coverage", "uk_target_surface", @@ -1784,6 +1787,7 @@ def test_strict_absent_evidence_entries_are_declared(self, manifest) -> None: "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", "uk_stage_spi_employment_shell_fit", + "uk_stage_aps_occupation_fit", "uk_weights_audit", # The #970 projection fence: a seam that cannot project cannot # certify the candidate's sub-exempt gainers. diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py new file mode 100644 index 0000000000..a48f7e3745 --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py @@ -0,0 +1,451 @@ +"""The APS sub-major draw: the donor cleaning, the draw, its keys, receipt and gate.""" + +from __future__ import annotations + +import copy +import json + +import numpy as np +import pandas as pd +import pytest + +from microcosm.build import load_country_spec +from microcosm.build.uk_runtime.aps_occupation import ( + UK_APS_OCCUPATION_CLEANING, + UK_APS_OCCUPATION_IMPUTATION, + UK_APS_OCCUPATION_OUTPUT, + UK_APS_PERSON_TAB_ROLE, + UKAPSOccupationStageTransform, + _assert_stage_parameters, + clean_aps_occupation_table, + impute_soc2020_sub_major_group, +) +from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP, + UK_SOC2020_MAJOR_GROUPS, + UK_SOC2020_SUB_MAJOR_GROUPS, +) +from microcosm.build.uk_runtime.stage_health import uk_stage_health_gate +from test_support.microcosm_build.uk_aps_occupation import ( + aps_raw_table, + occupation_frame_tables, + sub_major_codes, +) + +STAGE = "aps_occupation" + + +@pytest.fixture(scope="module") +def raw(): + return aps_raw_table() + + +@pytest.fixture(scope="module") +def donors(raw): + return clean_aps_occupation_table(raw) + + +@pytest.fixture(scope="module") +def tables(): + return occupation_frame_tables() + + +@pytest.fixture(scope="module") +def drawn(tables, donors): + person, household, weights = tables + return impute_soc2020_sub_major_group( + person, household, weights, donors[0], boosted_max_iter=60 + ) + + +def _stage(): + return next(s for s in load_country_spec("uk").sources.stages if s.stage == STAGE) + + +# --- the packaged stage ------------------------------------------------------ + + +def test_the_packaged_stage_matches_the_module_contract() -> None: + stage = _stage() + _assert_stage_parameters(stage) + assert stage.outputs == (UK_APS_OCCUPATION_OUTPUT,) + (artifact,) = stage.artifacts + assert artifact["role"] == UK_APS_PERSON_TAB_ROLE + assert artifact["ukds_study_number"] == 9408 + assert artifact["runtime_sha256_required"] is True + + +@pytest.mark.parametrize( + "position, path, value", + [ + (1, ("boosted_weight",), 1.0), + (1, ("unseen_categories",), "refuse"), + (0, ("codes", "region", "3"), "MERSEYSIDE"), + ], +) +def test_a_drifted_setting_is_refused(position, path, value) -> None: + stage = _stage() + operations = list(stage.operations) + parameters = copy.deepcopy(dict(operations[position].parameters)) + target = parameters + for key in path[:-1]: + target = target[key] + target[path[-1]] = value + operations[position] = type(operations[position])( + kind=operations[position].kind, parameters=parameters + ) + changed = type(stage)(**{**stage.__dict__, "operations": tuple(operations)}) + with pytest.raises(ValueError, match="parameters drifted"): + _assert_stage_parameters(changed) + + +def test_the_declared_settings_are_the_measured_blend() -> None: + assert UK_APS_OCCUPATION_IMPUTATION["boosted_weight"] == 0.5 + assert UK_APS_OCCUPATION_IMPUTATION["predictors"] == [ + "age", + "gender", + "region", + "status_group", + "employment_income", + "sic_section", + ] + assert UK_APS_OCCUPATION_IMPUTATION["evidence"]["grouping"] == "person" + assert UK_APS_OCCUPATION_CLEANING["codes"]["sections"][-1] == "U" + + +def test_a_digest_mismatch_is_refused(tmp_path) -> None: + tab = tmp_path / "apsp_a24m25_eul_pwta22.tab" + tab.write_text("AGE\tSEX\n30\t1\n") + transform = UKAPSOccupationStageTransform(stage=_stage(), aps_tab_path=tab) + with pytest.raises(ValueError, match="not the pinned"): + transform._raw_donor() + + +def test_a_missing_tab_is_refused() -> None: + with pytest.raises(ValueError, match="requires the caller-supplied APS"): + UKAPSOccupationStageTransform(stage=_stage())._raw_donor() + + +# --- the donor cleaning ----------------------------------------------------- + + +def test_cleaning_keeps_adults_with_a_minor_group_and_known_pay(raw, donors) -> None: + table, receipt = donors + employed = raw["ILODEFR"] == 1 + minor = np.where(employed, raw["SC20MMN"], raw["SC20LMN"]) + expected = ( + (raw["AGE"] >= 16) + & (raw["INECAC05"] != 26) + & (minor > 0) + & ((raw["INECAC05"] != 1) | (raw["GRSSWK"] >= 0)) + ) + assert len(table) == int(expected.sum()) + kept = raw.loc[expected] + np.testing.assert_allclose( + table["employment_income"].to_numpy(), + np.where(kept["GRSSWK"] >= 0, kept["GRSSWK"] * 52, 0.0), + ) + np.testing.assert_allclose( + table["weight"].to_numpy(), + np.where(kept["INECAC05"] == 1, kept["PIWTA22"], kept["PWTA22"]), + ) + assert table["age"].max() <= 80 + assert set(table["region"]) <= { + "NORTH_EAST", + "NORTH_WEST", + "LONDON", + "WALES", + "SCOTLAND", + "NORTHERN_IRELAND", + } + merseyside = (kept["GOVTOF"] == 3).to_numpy() + assert (table["region"].to_numpy()[merseyside] == "NORTH_WEST").all() + assert set(table["status_group"]) == { + "EMPLOYEE", + "SELF_EMPLOYED", + "RETIRED", + "OTHER", + } + assert set(table["sic_section"]) <= set("ABCDEFGHIJKLMNOPQRST") | {""} + nested = table["soc2020_sub_major_group"].map( + UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP + ) + assert (nested == table["soc2020_major_group"]).all() + assert receipt["dropped"]["no_region"] == 0 + assert receipt["dropped"]["employee_pay_unknown"] not in (0, "<3") + + +def test_an_unknown_minor_group_is_refused(raw) -> None: + broken = raw.copy() + row = int(np.flatnonzero(broken["SC20MMN"] > 0)[0]) + broken.loc[row, "SC20MMN"] = 991 + with pytest.raises(ValueError, match=r"\[991\] outside the sub-major groups"): + clean_aps_occupation_table(broken) + + +def test_a_missing_declared_column_is_refused(raw) -> None: + with pytest.raises(ValueError, match="lacks the declared columns"): + clean_aps_occupation_table(raw.drop(columns=["GOVTOF"])) + + +# --- the draw --------------------------------------------------------------- + + +def test_only_the_new_column_is_added(tables, drawn) -> None: + person, _, _ = tables + person_out, _, _ = drawn + pd.testing.assert_frame_equal( + person, person_out.drop(columns=[UK_APS_OCCUPATION_OUTPUT]) + ) + + +def test_none_stays_none_and_every_group_nests(tables, drawn) -> None: + person, _, _ = tables + person_out, _, _ = drawn + majors = person["soc2020_major_group"].to_numpy() + subs = person_out[UK_APS_OCCUPATION_OUTPUT].to_numpy() + assert ((subs == "NONE") == (majors == "NONE")).all() + nested = pd.Series(subs).map(UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP) + assert (nested.to_numpy() == majors).all() + assert set(subs) - {"NONE"} <= set(UK_SOC2020_SUB_MAJOR_GROUPS.values()) + + +def test_pay_moves_the_sub_major_group(tables, drawn) -> None: + person, household, _ = tables + person_out, _, _ = drawn + frs = ( + person["person_household_id"] + .isin( + household.loc[ + household["household_support_channel"] == "frs", "household_id" + ] + ) + .to_numpy() + ) + employee = (person["employment_status"] == "FT_EMPLOYED").to_numpy() & frs + pay = person["employment_income"].to_numpy() + majors = person["soc2020_major_group"].to_numpy() + first = { + UK_SOC2020_MAJOR_GROUPS[code]: UK_SOC2020_SUB_MAJOR_GROUPS[ + sub_major_codes(code)[0] + ] + for code in UK_SOC2020_MAJOR_GROUPS + } + is_first = np.asarray( + [ + sub == first.get(group) + for sub, group in zip( + person_out[UK_APS_OCCUPATION_OUTPUT], majors, strict=True + ) + ] + ) + high = employee & (pay > 52 * 900) + low = employee & (pay < 52 * 300) + assert is_first[high].mean() > 0.7 + assert is_first[low].mean() < 0.3 + + +def test_undrawn_copies_draw_their_twins_group(tables, drawn) -> None: + person, _, _ = tables + person_out, _, _ = drawn + copies = (person["person_id"] != person["person_source_id"]).to_numpy() & ~( + person["person_is_spi_income_recipient"].to_numpy() + ) + assert copies.any() + by_id = person_out.set_index("person_id")[UK_APS_OCCUPATION_OUTPUT] + twins = by_id.loc[person.loc[copies, "person_source_id"]].to_numpy() + assert (person_out.loc[copies, UK_APS_OCCUPATION_OUTPUT].to_numpy() == twins).all() + + +def test_draws_are_keyed_on_identities_not_positions(tables, donors, drawn) -> None: + person, household, weights = tables + person_out, _, _ = drawn + order = np.random.default_rng(4).permutation(len(person)) + shuffled, _, _ = impute_soc2020_sub_major_group( + person.iloc[order], household, weights, donors[0], boosted_max_iter=60 + ) + pd.testing.assert_frame_equal(shuffled.sort_index(), person_out.sort_index()) + + +def test_the_receipt_is_finite_json_with_banded_counts(drawn) -> None: + _, receipt, records = drawn + json.dumps(receipt, sort_keys=True, allow_nan=False) + held_out = receipt["held_out"] + assert held_out["status"] == "measured" + assert set(held_out["log_loss"]) == {"model", "boosted", "spline_logit", "marginal"} + assert held_out["log_loss"]["model"] < held_out["log_loss"]["marginal"] + assert set(held_out["major_groups"]) == set(UK_SOC2020_MAJOR_GROUPS.values()) + for entry in held_out["major_groups"].values(): + assert entry["support"] in {"<3", "3-9", "10-29", "30+"} + assert receipt["frame_against_donors"]["share_gap_max"] is not None + assert receipt["drawn"]["unseen_category_households"] == 0 + assert len(records) == 9 + # A DataFrame fit on stated donor weights resolves to "explicit". + assert {record.weight_kind for record in records} == {"explicit"} + + +def test_an_unseen_section_is_counted_not_refused(tables, donors) -> None: + person, household, weights = tables + changed = person.copy() + adults = np.flatnonzero(changed["soc2020_major_group"] != "NONE")[:6] + changed.loc[changed.index[adults], "sic_industry_division"] = 99 + _, receipt, _ = impute_soc2020_sub_major_group( + changed, household, weights, donors[0], boosted_max_iter=20 + ) + assert receipt["drawn"]["unseen_category_households"] == "3-9" + + +def test_too_few_donors_leave_the_evidence_unmeasured(tables) -> None: + person, household, weights = tables + thin, _ = clean_aps_occupation_table(aps_raw_table(n=200, seed=3)) + person_out, receipt, _ = impute_soc2020_sub_major_group( + person, household, weights, thin, boosted_max_iter=5 + ) + assert receipt["held_out"]["status"] == "not_measured" + assert (person_out[UK_APS_OCCUPATION_OUTPUT] != "NONE").sum() > 0 + + +def test_a_major_group_without_donors_is_refused(tables, donors) -> None: + person, household, weights = tables + table = donors[0] + without = table.loc[table["soc2020_major_group"] != "ELEMENTARY"] + with pytest.raises(ValueError, match="no donors in major group ELEMENTARY"): + impute_soc2020_sub_major_group( + person, household, weights, without, boosted_max_iter=5 + ) + + +def test_a_frame_already_carrying_the_output_is_refused(tables, donors) -> None: + person, household, weights = tables + with pytest.raises(ValueError, match="already carries"): + impute_soc2020_sub_major_group( + person.assign(soc2020_sub_major_group="NONE"), + household, + weights, + donors[0], + ) + + +def test_a_child_with_a_major_group_is_refused(tables, donors) -> None: + person, household, weights = tables + broken = person.copy() + child = int(np.flatnonzero(broken["employment_status"] == "CHILD")[0]) + broken.loc[broken.index[child], "soc2020_major_group"] = "ELEMENTARY" + with pytest.raises(ValueError, match="no occupation status group"): + impute_soc2020_sub_major_group( + broken, household, weights, donors[0], boosted_max_iter=5 + ) + + +# --- the sub_major_draw stage-health gate ------------------------------------- + + +def _gate_parameters() -> dict: + gates = load_country_spec("uk").gates + entry = next(e for e in gates.gates if e.id == "uk_stage_aps_occupation_fit") + assert (entry.gate, entry.phase) == ("stage_health", "transferred") + assert entry.population_fact_check and entry.evidence_absent_blocks + return dict(entry.parameters) + + +def _evidence(frame_gap: float | None = 0.02, **overrides) -> dict: + held_out = { + "status": "measured", + "log_loss": { + "model": 0.553, + "boosted": 0.559, + "spline_logit": 0.562, + "marginal": 0.927, + }, + "pay_band_share_gap": 0.003, + "region_share_gap": 0.004, + "major_groups": { + group: {"calibration_slope": 1.0, "calibration_outcome": "cross_fitted"} + for group in UK_SOC2020_MAJOR_GROUPS.values() + }, + } + held_out.update(overrides) + return { + "stage": STAGE, + "held_out": held_out, + "frame_against_donors": {"share_gap_max": frame_gap}, + } + + +def _gate(evidence: dict): + parameters = _gate_parameters() + return uk_stage_health_gate( + evidence=evidence, stage=STAGE, check=parameters["check"], parameters=parameters + ) + + +def test_the_gate_passes_the_measured_blend() -> None: + assert _gate(_evidence()).passed + + +_SLOPED = { + group: {"calibration_slope": 1.0, "calibration_outcome": "cross_fitted"} + for group in UK_SOC2020_MAJOR_GROUPS.values() +} + + +@pytest.mark.parametrize( + "evidence, message", + [ + ( + _evidence( + log_loss={ + "model": 0.8, + "boosted": 0.8, + "spline_logit": 0.81, + "marginal": 0.927, + } + ), + "below the constant", + ), + ( + _evidence( + log_loss={ + "model": 0.57, + "boosted": 0.559, + "spline_logit": 0.562, + "marginal": 0.927, + } + ), + "better learner", + ), + ( + _evidence( + major_groups={ + **_SLOPED, + "ELEMENTARY": { + "calibration_slope": 1.3, + "calibration_outcome": "cross_fitted", + }, + } + ), + "outside", + ), + ( + _evidence( + major_groups={ + **_SLOPED, + "SKILLED_TRADES": { + "calibration_slope": None, + "calibration_outcome": "cross_fitted_class_rates", + }, + } + ), + "could not be fitted", + ), + (_evidence(pay_band_share_gap=0.05), "pay bands"), + (_evidence(region_share_gap=0.05), "regions"), + (_evidence(frame_gap=0.12), "miss the donors"), + (_evidence(frame_gap=None), "no major group compares"), + (_evidence(status="not_measured", reason="thin"), "not measured"), + ], +) +def test_each_bound_fails_the_gate(evidence, message) -> None: + result = _gate(evidence) + assert not result.passed + assert any(message in failure for failure in result.failures) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py index 81610bc4b3..8f57fa9f50 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_battery_bindings.py @@ -1081,10 +1081,11 @@ def test_fully_armed_battery_evaluates_gate_for_gate(self) -> None: # amount, and the release-frame council-tax band check (#1278). # Plus uk_local_brma_enum_domain, the terminal recheck of the area-BRMA # rewrite (microcosm#1262; its enum_domain binding is stubbed here), and - # the SOC 2020 major group's enum check (microcosm#1490). - assert len(passed) == 23 + # the SOC 2020 major and sub-major groups' enum checks (microcosm#1490). + assert len(passed) == 24 assert "uk_local_brma_enum_domain" in passed assert "uk_soc2020_major_group_enum_domain" in passed + assert "uk_soc2020_sub_major_group_enum_domain" in passed def test_input_mass_parity_compares_the_release_surface(self) -> None: # The frame carries the spine's WAS property_wealth and the reference diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py index 63c6adca84..139d47a49c 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_frs_spine.py @@ -3983,6 +3983,7 @@ def test_input_artifact_pins_bind_spi_donor_and_ods() -> None: pins = tool._input_artifact_pins(stages) assert set(pins) == { + "aps_person_tab", "etb_household_tab", "lcfs_household_tab", "lcfs_person_tab", @@ -4014,6 +4015,7 @@ def test_input_artifact_pins_bind_spi_donor_and_ods() -> None: "lcfs_consumption", "etb_vat", "etb_services", + "aps_occupation", "hmrc_spi_income_spine", "hmrc_cgt_gains_spine", ) @@ -4073,6 +4075,10 @@ def test_e8_manifest_seeds_all_reach_the_build_sidecar_harvester() -> None: "student_loan_plan_5": 42, "student_loan_plan_2": 42, } + # microcosm#1490: the employment shell's keyed draws under its stage name, + # the APS draw under the column it writes. + assert declared["spi_employment_shell"] == {"spi_employment_shell": 0} + assert declared["aps_occupation"] == {"soc2020_sub_major_group": 0} def test_spine_sidecar_collects_stage_evidence_by_duck_type() -> None: diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py index 4baa4e3b9f..eb268a92d3 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_graph.py @@ -62,8 +62,8 @@ def test_uk_spine_graph_contains_every_manifest_stage() -> None: # uc_take_up and frs_annual_income_spells; microcosm#1428 the last stage, # trading_allowance_receipts; and company_cars after hmrc_spi_income_spine # (PolicyEngine/uk-autumn-budget-dashboard-2026#316); and microcosm#1490 - # spi_employment_shell after company_cars. - assert len(expected) == 53 + # spi_employment_shell after company_cars, then aps_occupation. + assert len(expected) == 54 assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(expected) assert set(expected) <= ids assert {"frs_hmrc_retained_leaves", "hmrc_spi_income"}.isdisjoint(ids) @@ -131,6 +131,7 @@ def test_uk_production_graph_binds_split_donor_sources_and_runtime_config() -> N "lcfs_household", "lcfs_person", "etb", + "aps", "spi", "hmrc_income", } @@ -143,6 +144,7 @@ def test_uk_production_graph_binds_split_donor_sources_and_runtime_config() -> N "nts_vehicle", ) assert graph.node("was_lisa").sources == ("was", "was_person") + assert graph.node("aps_occupation").sources == ("aps",) assert graph.node("hmrc_spi_income_spine").sources == ( "spi", "hmrc_income", diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py index f363bc8b60..d0a9741161 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_constants.py @@ -74,3 +74,24 @@ def test_sic_sections_are_ordered_and_disjoint() -> None: "P", "U", ] + + +def test_each_sub_major_group_nests_in_its_codes_major_group() -> None: + from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP, + UK_SOC2020_SUB_MAJOR_GROUPS, + ) + + codes = list(UK_SOC2020_SUB_MAJOR_GROUPS) + assert codes == sorted(codes) and len(codes) == 26 + assert {code // 10 for code in codes} == set(UK_SOC2020_MAJOR_GROUPS) + names = list(UK_SOC2020_SUB_MAJOR_GROUPS.values()) + assert len(set(names)) == len(names) + assert UK_SOC2020_NO_OCCUPATION not in names + assert dict(UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP) == { + UK_SOC2020_NO_OCCUPATION: UK_SOC2020_NO_OCCUPATION, + **{ + name: UK_SOC2020_MAJOR_GROUPS[code // 10] + for code, name in UK_SOC2020_SUB_MAJOR_GROUPS.items() + }, + } diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py new file mode 100644 index 0000000000..298369740c --- /dev/null +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py @@ -0,0 +1,48 @@ +"""Licensed-only: the APS donor cleaning covers the pinned SN 9408 tab. + +Skipped where the licensed tab is absent (CI is secrets-free by design). Set +POPULACE_UK_APS_TAB to the pinned apsp_a24m25_eul_pwta22.tab to run it. It +asserts structure only, never a count. +""" + +from __future__ import annotations + +import os +from pathlib import Path + +import pytest + +from microcosm.build import load_country_spec +from microcosm.build.uk_runtime.aps_occupation import ( + UK_APS_OCCUPATION_CLEANING, + UK_APS_PERSON_TAB_ROLE, + _artifact, + clean_aps_occupation_table, +) +from microcosm.build.uk_runtime.frs_spine import REGION_MAP, read_pinned_tab +from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_SUB_MAJOR_GROUPS, +) + + +def test_the_aps_cleaning_maps_every_code_of_the_licensed_tab() -> None: + tab = os.environ.get("POPULACE_UK_APS_TAB") + if not tab or not Path(tab).is_file(): + pytest.skip("licensed APS tab not available (set POPULACE_UK_APS_TAB)") + stage = next( + s for s in load_country_spec("uk").sources.stages if s.stage == "aps_occupation" + ) + raw = read_pinned_tab( + Path(tab), + _artifact(stage, UK_APS_PERSON_TAB_ROLE), + columns=list(UK_APS_OCCUPATION_CLEANING["columns"].values()), + ) + donors, receipt = clean_aps_occupation_table(raw) + assert set(donors["soc2020_sub_major_group"]) == set( + UK_SOC2020_SUB_MAJOR_GROUPS.values() + ) + assert set(donors["region"]) == set(REGION_MAP.values()) + assert set(donors["gender"]) == {"MALE", "FEMALE"} + assert receipt["dropped"]["no_region"] == 0 + assert receipt["dropped"]["no_sex"] == 0 + assert (donors["weight"] > 0).all() diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py index e30ab3d97a..3766f86157 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py @@ -72,8 +72,10 @@ # (PolicyEngine/uk-autumn-budget-dashboard-2026#316). "company_cars", # The employment shell redraws the drawn rows' occupation from that carved - # pay, before the housing shell (microcosm#1490). + # pay, before the housing shell, and the sub-major group is drawn within + # the major group it settles (microcosm#1490). "spi_employment_shell", + "aps_occupation", ] HOUSING_SHELL_STAGE_NAMES = [ "spi_housing_shell", @@ -322,6 +324,7 @@ def test_country_stage_plan_assembles_spine_plan(self) -> None: "trading_allowance_receipts": _identity, "company_cars": _identity, "spi_employment_shell": _identity, + "aps_occupation": _identity, "childcare_copy_take_up": _identity, "age_tail": _identity, "frs_relationships": _identity, diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py index 142a932836..6f1467cee2 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spine_acceptance_receipt.py @@ -184,6 +184,10 @@ def _apply_pending_roster_transformations( # rows' occupation from the pay the company cars carve. assert "spi_employment_shell" not in roster roster.insert(roster.index("company_cars") + 1, "spi_employment_shell") + # microcosm#1490 re-mint pending: the APS sub-major group is drawn within + # the major group the employment shell settles. + assert "aps_occupation" not in roster + roster.insert(roster.index("spi_employment_shell") + 1, "aps_occupation") # microcosm#1428 re-mint pending: the self-employed's gross receipts run # last. assert "trading_allowance_receipts" not in roster diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index 9e7bf9a82c..ea20926535 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -475,13 +475,13 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: # fingerprint derives from the manifest digest. Editing the spec moves all # three here in the same reviewed change. _UK_GATE_BATTERY_POLICY_SHA256 = ( - "7329732e070d3c10aef9ea50b9cd330c4187480b2fbcfc0b65ab1146fdfd75df" + "97ec5dd9ee1f1809412c5a3513b9471963f359ae3a501871fb8ace91520820f8" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "e83191ad38751ba75b8d1ed45352033f3d89851b7a2ec93b01e993a26c9498df" + "c790fadd40555b6062380b29b6c83f8c1cdec3ca6af5e1ad32fec71e0291d6f6" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "8dba276a743e06d300be96dd7e390fea9e56455fae016ac4d0a995fd04e5ae87" + "5fe0c71990495612dc6afc06215b66fb5e8b15558a4a6271416f59d3b3af5bcb" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -507,6 +507,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_uc_deduction_combination_enum_domain": "enum_domain", "uk_student_loan_plan_enum_domain": "enum_domain", "uk_soc2020_major_group_enum_domain": "enum_domain", + "uk_soc2020_sub_major_group_enum_domain": "enum_domain", "uk_council_tax_band_domain_terminal": "enum_domain", "uk_target_surface": "target_surface", "uk_target_fit": "target_fit", @@ -589,6 +590,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_stage_isa_subscriptions": ("stage_health", "transferred"), "uk_stage_company_cars_invariants": ("stage_health", "transferred"), "uk_stage_spi_employment_shell_fit": ("stage_health", "transferred"), + "uk_stage_aps_occupation_fit": ("stage_health", "transferred"), "uk_stage_frs_take_up_signal": ("stage_health", "assembled"), "uk_stage_frs_person_draws_take_up_signal": ("stage_health", "assembled"), "uk_stage_frs_household_draws_take_up_signal": ("stage_health", "assembled"), @@ -619,6 +621,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_uc_deduction_combination_enum_domain": ("enum_domain", "terminal"), "uk_student_loan_plan_enum_domain": ("enum_domain", "terminal"), "uk_soc2020_major_group_enum_domain": ("enum_domain", "terminal"), + "uk_soc2020_sub_major_group_enum_domain": ("enum_domain", "terminal"), "uk_council_tax_band_domain_terminal": ("enum_domain", "terminal"), "uk_calibration_reference_coverage": ( "calibration_reference_coverage", @@ -706,6 +709,7 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "uk_stage_isa_subscriptions", "uk_stage_company_cars_invariants", "uk_stage_spi_employment_shell_fit", + "uk_stage_aps_occupation_fit", "uk_stage_frs_take_up_signal", "uk_stage_frs_person_draws_take_up_signal", "uk_stage_frs_household_draws_take_up_signal", @@ -945,6 +949,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: "uk_stage_isa_subscriptions_invariants", "uk_stage_company_cars_invariants", "uk_stage_spi_employment_shell_fit", + "uk_stage_aps_occupation_fit", "uk_stage_lcfs_consumption_basis", "uk_stage_lcfs_consumption_bus_pricing", "uk_stage_lcfs_consumption_energy_rake", @@ -1001,6 +1006,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: "uk_release_input_coverage_manifest_current", "uk_student_loan_plan_enum_domain", "uk_soc2020_major_group_enum_domain", + "uk_soc2020_sub_major_group_enum_domain", "uk_council_tax_band_domain_terminal", "uk_support", "uk_take_up_signal", @@ -1012,10 +1018,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: _UK_CERTIFICATION_PART_DIGESTS: Mapping[str, Mapping[str, str]] = { "spine": { "gates_manifest_sha256": ( - "9d9d85efebb2f43ccbac86a3f1075c97a869ae3f46b95cf3ce2fd876a2ffecc8" + "bb78d2be103399c9cf59eec229199ccab5aeddbc925db9c999944e473281125e" ), "policy_sha256": ( - "f8eb18ad80403344041a7c8dab73b36bf424ab5c621cf7a146417e34d88f8ee6" + "0a2635b7b22034ee1fa9b6574bc259805397171b367f4c7941509648704bf1bb" ), }, "calibration_seam": { @@ -1028,10 +1034,10 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: }, "release_cut": { "gates_manifest_sha256": ( - "fc2f2669d2c73f8a50df9fbf8d42df2cb1e05142b531ef16409445f938547278" + "b4a55e285e36599f222db70e034dfd2176e4d3dfb1d04d92691fa80e2d85d840" ), "policy_sha256": ( - "9fa54cd666e8768404729d349855636a13026a0a719164f4f83ec5e68d98620e" + "ec9c19267423146f8f9d88353381b932d20bfbb692e3c7d027224914adb9fb2a" ), }, } diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index 60c8f4b618..2531b81a13 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -224,13 +224,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 = ( - "7329732e070d3c10aef9ea50b9cd330c4187480b2fbcfc0b65ab1146fdfd75df" + "97ec5dd9ee1f1809412c5a3513b9471963f359ae3a501871fb8ace91520820f8" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "e83191ad38751ba75b8d1ed45352033f3d89851b7a2ec93b01e993a26c9498df" + "c790fadd40555b6062380b29b6c83f8c1cdec3ca6af5e1ad32fec71e0291d6f6" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "8dba276a743e06d300be96dd7e390fea9e56455fae016ac4d0a995fd04e5ae87" + "5fe0c71990495612dc6afc06215b66fb5e8b15558a4a6271416f59d3b3af5bcb" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "f246388de42654dd68dbbb40c42282001b5b0a8bf48976162bcb1199085cb1d3" @@ -376,6 +376,7 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "uk_stage_isa_subscriptions": ("stage_health", "transferred", None), "uk_stage_company_cars_invariants": ("stage_health", "transferred", None), "uk_stage_spi_employment_shell_fit": ("stage_health", "transferred", None), + "uk_stage_aps_occupation_fit": ("stage_health", "transferred", None), "uk_stage_frs_take_up_signal": ( "stage_health", "assembled", @@ -469,6 +470,11 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "terminal", "enum_domain", ), + "uk_soc2020_sub_major_group_enum_domain": ( + "enum_domain", + "terminal", + "enum_domain", + ), "uk_council_tax_band_domain_terminal": ( "enum_domain", "terminal", @@ -1479,6 +1485,7 @@ def _gate_battery_payload( "uk_stage_isa_subscriptions": "isa_subscriptions", "uk_stage_company_cars_invariants": "company_cars", "uk_stage_spi_employment_shell_fit": "spi_employment_shell", + "uk_stage_aps_occupation_fit": "aps_occupation", "uk_stage_frs_take_up_signal": "frs_take_up", "uk_stage_frs_person_draws_take_up_signal": "frs_person_draws", "uk_stage_frs_household_draws_take_up_signal": "frs_household_draws", diff --git a/packages/microcosm-fit/src/microcosm/fit/categorical.py b/packages/microcosm-fit/src/microcosm/fit/categorical.py index f13918ff4d..b092822732 100644 --- a/packages/microcosm-fit/src/microcosm/fit/categorical.py +++ b/packages/microcosm-fit/src/microcosm/fit/categorical.py @@ -18,6 +18,13 @@ The fit follows the package's weight contract (:mod:`microcosm.fit.model`): a Frame fit reads the owning entity's typed weights, a DataFrame fit needs them stated, and ``weights="none"`` is the only unweighted path. + +A category the fit never saw is refused at prediction by default. A model that +predicts for another survey's rows can choose ``unseen_categories="ignore"`` +instead: such a category then sets none of its predictor's indicators, as +scikit-learn's ``handle_unknown="ignore"`` encodes it, and +:meth:`FittedCategoricalClassifier.unseen_category_rows` says which rows held +one. """ from __future__ import annotations @@ -53,6 +60,8 @@ #: Added to a feature's standard deviation so a constant column scales to zero. _SCALE_FLOOR = 1e-9 +#: How a category the fit never saw is read at prediction. +_UNSEEN_CATEGORY_RULES = ("refuse", "ignore") @dataclass(frozen=True) @@ -137,6 +146,9 @@ class CategoricalClassifier: tames long-tailed amounts such as incomes. The boosted classifier, which splits on ranks, always sees the raw values. seed: Seeds the boosted classifier and the :meth:`predict` draws. + unseen_categories: ``"refuse"`` (the default) raises when a row to + predict holds a category the fit never saw; ``"ignore"`` sets none + of that predictor's indicators for it. """ boosted_weight: float = 0.5 @@ -145,11 +157,16 @@ class CategoricalClassifier: categorical_predictors: tuple[str, ...] = () arcsinh_scales: Mapping[str, float] = field(default_factory=dict) seed: int = 0 + unseen_categories: str = "refuse" def __post_init__(self) -> None: weight = float(self.boosted_weight) if not 0.0 <= weight <= 1.0: raise ValueError("boosted_weight must be in [0, 1].") + if self.unseen_categories not in _UNSEEN_CATEGORY_RULES: + raise ValueError( + f"unseen_categories must be one of {list(_UNSEEN_CATEGORY_RULES)}." + ) for column, scale in self.arcsinh_scales.items(): if not np.isfinite(scale) or scale <= 0: raise ValueError(f"arcsinh scale for {column!r} must be positive.") @@ -210,7 +227,9 @@ def fit( if weight_values is None else np.asarray(weight_values, dtype=np.float64) ) - features = _Features.fit(table, predictors, self.categorical_predictors) + features = _Features.fit( + table, predictors, self.categorical_predictors, self.unseen_categories + ) classes = np.unique(y) fitted = FittedCategoricalClassifier( entity=entity, @@ -260,16 +279,22 @@ class _Features: numeric: tuple[str, ...] categorical: tuple[str, ...] levels: Mapping[str, np.ndarray] + unseen: str = "refuse" @classmethod def fit( - cls, table: pd.DataFrame, predictors: list[str], categorical: Sequence[str] + cls, + table: pd.DataFrame, + predictors: list[str], + categorical: Sequence[str], + unseen: str = "refuse", ) -> _Features: numeric = tuple(c for c in predictors if c not in categorical) features = cls( numeric=numeric, categorical=tuple(c for c in predictors if c in categorical), levels={}, + unseen=unseen, ) features.numeric_values(table) features.levels = { @@ -291,17 +316,27 @@ def numeric_values(self, table: pd.DataFrame) -> np.ndarray: raise ValueError(f"Numeric predictors have non-finite values: {bad}.") return values + def _indicators(self, table: pd.DataFrame, column: str) -> np.ndarray: + values = table[column].to_numpy() + return values[:, None] == self.levels[column][None, :] + + def unseen_rows(self, table: pd.DataFrame) -> np.ndarray: + rows = np.zeros(len(table), dtype=bool) + for column in self.categorical: + rows |= ~self._indicators(table, column).any(axis=1) + return rows + def one_hot(self, table: pd.DataFrame) -> np.ndarray: parts = [] for column in self.categorical: - values = table[column].to_numpy() - known = self.levels[column] - unseen = sorted({str(v) for v in values} - {str(v) for v in known}) - if unseen: + indicators = self._indicators(table, column) + seen = indicators.any(axis=1) + if self.unseen == "refuse" and not seen.all(): + unseen = sorted({str(v) for v in table[column].to_numpy()[~seen]}) raise ValueError( f"Predictor {column!r} has categories the fit never saw: {unseen}." ) - parts.append((values[:, None] == known[None, :]).astype(np.float64)) + parts.append(indicators.astype(np.float64)) if not parts: return np.zeros((len(table), 0)) return np.hstack(parts) @@ -480,6 +515,10 @@ def predict_proba(self, frame_or_df: Frame | pd.DataFrame) -> np.ndarray: weight * components["boosted"] + (1.0 - weight) * components["spline_logit"] ) + def unseen_category_rows(self, frame_or_df: Frame | pd.DataFrame) -> np.ndarray: + """Rows holding a category of some categorical predictor the fit never saw.""" + return self._features.unseen_rows(self._table(frame_or_df)) + def predict_from_uniforms( self, frame_or_df: Frame | pd.DataFrame, uniforms: np.ndarray ) -> pd.DataFrame: diff --git a/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py b/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py index a673dbb80f..1da2b42741 100644 --- a/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py +++ b/packages/microcosm-fit/tests/engine_free/shared/test_categorical.py @@ -175,6 +175,22 @@ def test_unseen_categories_at_prediction_are_refused() -> None: fitted.predict_proba(data.assign(group="east")) +def test_ignored_unseen_categories_set_no_indicator() -> None: + data = _planted() + fitted = _model(unseen_categories="ignore").fit( + data, PREDICTORS, ["label"], weights="weight" + ) + east = data.head(50).assign(group="east") + proba = fitted.predict_proba(east) + np.testing.assert_allclose(proba.sum(axis=1), 1.0) + # Every unseen level reads alike: none of the group's indicators is set. + np.testing.assert_allclose( + proba, fitted.predict_proba(data.head(50).assign(group="west")) + ) + assert fitted.unseen_category_rows(east).all() + assert not fitted.unseen_category_rows(data).any() + + def test_non_finite_numeric_predictors_are_refused() -> None: data = _planted() data.loc[3, "pay"] = np.nan @@ -194,6 +210,7 @@ def test_a_missing_label_is_refused() -> None: [ ({"boosted_weight": 1.5}, "boosted_weight"), ({"arcsinh_scales": {"pay": 0.0}}, "positive"), + ({"unseen_categories": "drop"}, "unseen_categories"), ], ) def test_bad_settings_are_refused(overrides, message) -> None: diff --git a/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py b/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py index 7830b3d739..6dfb515081 100644 --- a/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py +++ b/packages/microcosm-frame/src/microcosm/frame/adapters/policyengine_uk_concepts.py @@ -454,13 +454,6 @@ "microcosm#1439 stores the status and retires the encoding (for María's " "signature)." ), - "soc2020_sub_major_group": ( - "The SOC 2020 sub-major group of the same job (policyengine-uk " - "2.173.0). The FRS codes the major group only, so the sub-major group " - "needs an imputation within it from a survey that codes it. Until a " - "stage imputes it every person takes NONE, and no engine formula reads " - "it (microcosm#1490; for María's signature)." - ), "is_in_full_time_education": ( "Whether the person is on a full-time course (policyengine-uk 2.173.2), " "which Universal Credit's condition that a claimant is not receiving " diff --git a/test_support/microcosm_build/uk_aps_occupation.py b/test_support/microcosm_build/uk_aps_occupation.py new file mode 100644 index 0000000000..27bcef3ae2 --- /dev/null +++ b/test_support/microcosm_build/uk_aps_occupation.py @@ -0,0 +1,171 @@ +"""Synthetic APS donors and frame tables for the APS occupation stage tests. + +Within every major group an employee's APS sub-major group follows pay: the +group's first sub-major group above the group's median weekly pay, one of the +others below it. Everyone else draws a sub-major group at random. The frame's +FRS households hold an adult and a partner with a major group and a child with +none; each SPI household copies one, with its adult an SPI income recipient on +a high drawn pay and its partner and child exact copies of the twin's. +""" + +from __future__ import annotations + +import numpy as np +import pandas as pd + +from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_MAJOR_GROUPS, + UK_SOC2020_SUB_MAJOR_GROUPS, +) + +#: APS government office region codes the donors live in: Merseyside (3) and +#: the nations included. +_GOVTOF = (1, 2, 3, 8, 11, 12, 13) +_REGIONS = ("NORTH_EAST", "NORTH_WEST", "LONDON", "WALES", "SCOTLAND") +#: SIC 2007 divisions the frame's adults work in; 99 (section U) is a section +#: no donor holds. +_DIVISIONS = (47, 85, 86, 62, 43) + + +def sub_major_codes(major: int) -> list[int]: + """A major group's sub-major group codes, in code order.""" + return [code for code in UK_SOC2020_SUB_MAJOR_GROUPS if code // 10 == major] + + +def aps_raw_table(n: int = 5400, seed: int = 0) -> pd.DataFrame: + """APS person rows under the codebook's names, with the planted pay rule. + + Besides the donors there are under-16s, adults without a minor group and + employees whose pay is unknown, which the cleaning drops. + """ + + rng = np.random.default_rng(seed) + major = rng.integers(1, 10, n) + employed = rng.random(n) < 0.8 + status = np.where( + employed, + np.where(rng.random(n) < 0.85, 1, 2), + rng.choice([16, 24, 5, 20], n), + ) + weekly = rng.lognormal(6.3, 0.6, n) + employee = status == 1 + pay_known = employee & (rng.random(n) < 0.85) + sub = np.empty(n, dtype=np.int64) + for group in range(1, 10): + codes = np.asarray(sub_major_codes(group)) + rows = major == group + high = weekly[rows] > np.median(weekly[rows & pay_known]) + planted = np.where(high, codes[0], rng.choice(codes[1:], rows.sum())) + random = rng.choice(codes, rows.sum()) + noisy = rng.random(rows.sum()) < 0.1 + sub[rows] = np.where(pay_known[rows] & ~noisy, planted, random) + minor = sub * 10 + 1 + coded = rng.random(n) < 0.95 + age = rng.integers(16, 86, n) + child = rng.random(n) < 0.03 + section = rng.integers(1, 21, n) # never 21, section U + return pd.DataFrame( + { + "AGE": np.where(child, 15, age), + "SEX": rng.integers(1, 3, n), + "GOVTOF": rng.choice(_GOVTOF, n), + "ILODEFR": np.where(employed, 1, 3), + "INECAC05": np.where(child, 26, status), + "SC20MMN": np.where(employed & coded, minor, -9), + "SC20LMN": np.where(~employed & coded, minor, -9), + "GRSSWK": np.where( + pay_known, np.round(weekly, 2), np.where(employee, -8, -9) + ), + "PWTA22": rng.uniform(500.0, 1500.0, n), + "PIWTA22": np.where(pay_known, rng.uniform(800.0, 2000.0, n), -9.0), + "INDS07M": np.where(employed, section, -9), + "INDS07L": np.where(~employed, section, -9), + "CASENO": np.arange(n), + } + ) + + +def occupation_frame_tables(n_frs: int = 900, n_spi: int = 150, seed: int = 0): + """FRS households and SPI copies of some, as the employment shell leaves them. + + Returns ``(person, household, household_weights)``. FRS rows' source ids + are their own; a copy's ``person_source_id`` is its twin's person id and + its ``household_source_id`` the twin's household. + """ + + rng = np.random.default_rng(seed) + majors = np.asarray(list(UK_SOC2020_MAJOR_GROUPS.values()), dtype=object) + household_id = np.arange(1, n_frs + 1) + household = pd.DataFrame( + { + "household_id": household_id, + "household_support_channel": "frs", + "household_source_id": household_id, + "region": rng.choice(_REGIONS, n_frs), + } + ) + + def adults(status_draw: np.ndarray) -> pd.DataFrame: + return pd.DataFrame( + { + "person_household_id": household_id, + "age": rng.integers(18, 90, n_frs), + "gender": rng.choice(["MALE", "FEMALE"], n_frs), + "employment_status": status_draw, + "employment_income": np.where( + status_draw == "FT_EMPLOYED", rng.lognormal(10.25, 0.6, n_frs), 0.0 + ), + "sic_industry_division": rng.choice(_DIVISIONS, n_frs).astype(np.int64), + "soc2020_major_group": rng.choice(majors, n_frs), + "person_is_spi_income_recipient": False, + } + ) + + statuses = np.array(["FT_EMPLOYED", "FT_SELF_EMPLOYED", "RETIRED", "UNEMPLOYED"]) + adult = adults(statuses[rng.choice(4, n_frs, p=[0.75, 0.1, 0.1, 0.05])]) + partner = adults(statuses[rng.choice(4, n_frs, p=[0.75, 0.1, 0.1, 0.05])]) + child = pd.DataFrame( + { + "person_household_id": household_id, + "age": np.full(n_frs, 9), + "gender": rng.choice(["MALE", "FEMALE"], n_frs), + "employment_status": "CHILD", + "employment_income": 0.0, + "sic_industry_division": np.zeros(n_frs, dtype=np.int64), + "soc2020_major_group": "NONE", + "person_is_spi_income_recipient": False, + } + ) + frs = pd.concat([adult, partner, child], ignore_index=True) + frs.insert(0, "person_id", np.arange(1, len(frs) + 1) * 10) + frs["person_source_id"] = frs["person_id"] + + twins = rng.choice(household_id, n_spi, replace=False) + copies = [] + for index, twin in enumerate(twins): + copy = frs.loc[frs["person_household_id"] == twin].copy() + copy["person_source_id"] = copy["person_id"] + copy["person_household_id"] = n_frs + index + 1 + lead = copy.index[0] + copy.loc[lead, "person_is_spi_income_recipient"] = True + copy.loc[lead, "employment_status"] = "FT_EMPLOYED" + copy.loc[lead, "employment_income"] = rng.lognormal(12.3, 0.4) + copies.append(copy) + spi = pd.concat(copies, ignore_index=True) + spi["person_id"] = 100_000 + np.arange(len(spi)) * 10 + person = pd.concat([frs, spi], ignore_index=True) + spi_households = pd.DataFrame( + { + "household_id": n_frs + np.arange(1, n_spi + 1), + "household_support_channel": "spi", + "household_source_id": twins, + "region": household.set_index("household_id") + .loc[twins, "region"] + .to_numpy(), + } + ) + household = pd.concat([household, spi_households], ignore_index=True) + weights = np.concatenate( + [rng.uniform(500.0, 1500.0, n_frs), rng.uniform(5.0, 50.0, n_spi)] + ) + return person, household, weights diff --git a/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index c0fab11b29..b4edff878d 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -28,6 +28,7 @@ from microcosm.build.country_spec import country_stage_plan, load_country_spec from microcosm.build.source_manifest import SourceManifest, SourceStageSpec from microcosm.build.uk_runtime.age_tail import UKAgeTailStageTransform +from microcosm.build.uk_runtime.aps_occupation import UKAPSOccupationStageTransform from microcosm.build.uk_runtime.carers_allowance_take_up import ( UKCarersAllowanceTakeUpStageTransform, ) @@ -132,6 +133,9 @@ UKLegacyClosureTakeUpStageTransform, ) from microcosm.build.uk_runtime.nts_bus_travel import UKNTSBusTravelStageTransform +from microcosm.build.uk_runtime.occupation_constants import ( + UK_SOC2020_SUB_MAJOR_GROUPS, +) from microcosm.build.uk_runtime.pension_credit_take_up import ( UKPensionCreditTakeUpStageTransform, ) @@ -215,7 +219,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 = 53 +UK_FIXTURE_STAGE_COUNT = 54 _QRF_ESTIMATORS = 4 # These are the complete object-string surface observed in the unchanged @@ -1434,6 +1438,42 @@ def _etb_donor() -> pd.DataFrame: ) +def _aps_donor() -> pd.DataFrame: + """APS person rows under the codebook's names: three per sub-major group. + + Each sub-major group has an employee with pay, a self-employed worker and a + retired adult coded by the last job, so every major group has donors; an + under-16 and an employee without pay are there for the cleaning to drop. + """ + + rows: list[dict[str, float]] = [] + for index, code in enumerate(UK_SOC2020_SUB_MAJOR_GROUPS): + minor = code * 10 + 1 + for kind in range(3): + row = 3 * index + kind + employed = kind < 2 + rows.append( + { + "AGE": 20 + row % 60, + "SEX": 1 + row % 2, + "GOVTOF": 1 + row % 13, + "ILODEFR": 1 if employed else 3, + "INECAC05": (1, 2, 16)[kind], + "SC20MMN": minor if employed else -9, + "SC20LMN": -9 if employed else minor, + "GRSSWK": 300.0 + 25.0 * row if kind == 0 else -9.0, + "PWTA22": 500.0 + row, + "PIWTA22": 900.0 + row if kind == 0 else -9.0, + "INDS07M": 1 + row % 20 if employed else -9, + "INDS07L": -9 if employed else 1 + row % 20, + } + ) + dropped = dict(rows[0]) + rows.append({**dropped, "AGE": 15, "INECAC05": 26}) + rows.append({**dropped, "GRSSWK": -8.0, "PIWTA22": -9.0}) + return pd.DataFrame(rows) + + def _spi_donor() -> pd.DataFrame: rows: list[dict[str, float]] = [] for index in range(_DONOR_ROWS): @@ -2211,6 +2251,7 @@ def _build_implementations( lcfs_household: pd.DataFrame, lcfs_person: pd.DataFrame, etb: pd.DataFrame, + aps: pd.DataFrame, spi_donor: pd.DataFrame, income_targets: HMRCIncomeTargetSet, cgt_distribution: HMRCCapitalGainsJointDistribution, @@ -2366,6 +2407,11 @@ def capture_root(frame: Frame) -> Frame: "spi_employment_shell": UKSPIEmploymentShellStageTransform( stage=stages["spi_employment_shell"], boosted_max_iter=_QRF_ESTIMATORS ), + "aps_occupation": UKAPSOccupationStageTransform( + stage=stages["aps_occupation"], + donor=aps, + boosted_max_iter=_QRF_ESTIMATORS, + ), "spi_housing_shell": UKSPIHousingShellStageTransform( stage=stages["spi_housing_shell"], n_estimators=_QRF_ESTIMATORS ), @@ -2526,6 +2572,7 @@ def generate(output: Path) -> None: nts_vehicle = _nts_vehicles(nts_household) lcfs_household, lcfs_person = _lcfs_donors() etb = _etb_donor() + aps = _aps_donor() spi_donor = _spi_donor() _write_csv(sources / "was.csv", was) _write_csv(sources / "was_person.csv", was_person) @@ -2538,6 +2585,7 @@ def generate(output: Path) -> None: _write_csv(sources / "lcfs_household.csv", lcfs_household) _write_csv(sources / "lcfs_person.csv", lcfs_person) _write_csv(sources / "etb.csv", etb) + _write_csv(sources / "aps.csv", aps) _write_csv(sources / "spi_donor.csv", spi_donor) income_targets = _hmrc_income_targets(Path("synthetic-hmrc.ods")) @@ -2566,6 +2614,7 @@ def generate(output: Path) -> None: lcfs_household=lcfs_household, lcfs_person=lcfs_person, etb=etb, + aps=aps, spi_donor=spi_donor, income_targets=income_targets, cgt_distribution=cgt_distribution, @@ -2654,6 +2703,7 @@ def generate(output: Path) -> None: "lcfs_household": "lcfs_household.csv", "lcfs_person": "lcfs_person.csv", "etb": "etb.csv", + "aps": "aps.csv", "spi_donor": "spi_donor.csv", "hmrc_income_targets": "hmrc_income_targets.json", "cgt_distribution": "cgt_distribution.json", From 7b04de77fe390ebad89e012509f10dd698c888d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 16:19:40 +0000 Subject: [PATCH 5/7] Address the first review of #1512: status-matched industry copy, employee pay, nesting guard The employment shell's industry copy now draws within one cell: the drawn group crossed with the row's own status group, taking the 50 nearest donors, or all of the cell's donors where it holds fewer. A copied sector is therefore always one the row's status group holds, and every (group, section) pair occurs. The group-only and everyone levels are gone. A row now draws only among the groups that FRS adults of its own status group hold: the other groups' probabilities go to zero and the rest are renormalised. The cell is never empty, and a row whose status group holds none of the groups refuses the stage. On FRS 2024-25 at full scale every such cell holds at least 50 adults, so the restriction removes nothing there. The receipt reports the rows whose draw it restricts, and the donors of another status group (zero by construction). The held-out industry evidence leaves out, and counts, any adult whose cell has no donor in the other folds. Both stages read the SPI tape's PAY (hmrc_spi_pay) as an SPI income recipient's pay. Its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. In aps_occupation, pay is an employee's on both sides, because the APS asks GRSSWK of employees only. It is zero outside the EMPLOYEE status group on the frame, and zero for non-employee donors. On the pinned APS tab and FRS 2024-25 the stage's held-out figures barely move (pooled log loss 0.5526, against 0.5527 before). The gate's notes now cite slopes of 0.95 to 1.01. A new test holds that no stage after aps_occupation writes either occupation column, so the sub-major group stays nested in the major group on the shipped frame. The operations declare the new pay and draw-support rules. The gate notes move the battery's manifest digest and fingerprint and the spine part's manifest digest, and the coverage manifest is regenerated. Co-Authored-By: Claude Opus 5.5 --- .../spec_engine/schema/sources.schema.json | 12 ++ .../src/microcosm/build/uk/gates.json | 2 +- .../uk/release_input_coverage_manifest.json | 50 ++++---- .../src/microcosm/build/uk/source_stages.json | 7 +- .../src/microcosm/build/uk/spec/sources.yaml | 7 +- .../build/uk_runtime/aps_occupation.py | 50 ++++++-- .../src/microcosm/build/uk_runtime/graph.py | 1 + .../build/uk_runtime/spi_employment_shell.py | 116 +++++++++++++++--- .../engine_free/uk/test_uk_aps_occupation.py | 32 ++++- .../engine_free/uk/test_uk_source_stages.py | 12 ++ .../uk/test_uk_spi_employment_shell.py | 64 ++++++++-- .../src/microcosm/data/contract.py | 6 +- .../tests/engine_free/shared/test_contract.py | 4 +- .../microcosm_build/uk_aps_occupation.py | 10 +- 14 files changed, 294 insertions(+), 79 deletions(-) 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 f506fd2041..7be9ab093d 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 @@ -8750,6 +8750,8 @@ "training_rows", "rows", "identity", + "pay", + "draw_support", "seed", "occupation", "industry", @@ -8768,6 +8770,12 @@ "identity": { "type": "string" }, + "pay": { + "type": "string" + }, + "draw_support": { + "type": "string" + }, "seed": { "type": "integer" }, @@ -9155,6 +9163,7 @@ "within", "rows", "identity", + "pay", "seed", "predictors", "categorical_predictors", @@ -9182,6 +9191,9 @@ "identity": { "type": "string" }, + "pay": { + "type": "string" + }, "seed": { "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 cd07a3055a..8fa286211e 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/gates.json +++ b/packages/microcosm-build/src/microcosm/build/uk/gates.json @@ -1117,7 +1117,7 @@ "maximum_blend_log_loss_excess": 0.005, "maximum_frame_share_gap": 0.1 }, - "notes": "Stage-time check of the aps_occupation receipt's held-out evidence (microcosm#1490): within each major group, five stratified folds by person (the APS End User Licence file has no household identifier), scored on the APS donors. It fails when the evidence was not measured; when the model's out-of-fold log loss, pooled over the major groups by donor weight, is not at least minimum_log_loss_gain below the constant's (each group's training folds' class shares); when the blend's pooled log loss exceeds its better learner's by more than maximum_blend_log_loss_excess; when a major group's calibration slope falls outside calibration_slope_bounds or its Platt fit fell back to class rates; when the pooled gap between predicted and observed sub-major shares within the pay bands exceeds maximum_pay_band_share_gap, or within the regions maximum_region_share_gap; or when, in a major group resting on at least three FRS households, the FRS rows' expected sub-major shares miss the donors' by more than maximum_frame_share_gap (total variation), which bounds how far the FRS's own mix of age, sex, region, status, pay and section within a group moves the draw from the APS. The bounds sit wide of the stage measured on the APS April 2024 - March 2025 donors and FRS 2024-25 adults: a pooled log-loss gain of 0.37 (0.553 against 0.927), slopes of 0.96 to 1.01, a pay-band gap of 0.003, a region gap of 0.005, a log loss 0.006 below its better learner, and FRS rows' expected shares within 0.060 of the donors' (professional occupations; the other groups within 0.047). A population fact check: a synthetic smoke build records it without blocking, since a fixture of a few donors cannot fit the population's model." + "notes": "Stage-time check of the aps_occupation receipt's held-out evidence (microcosm#1490): within each major group, five stratified folds by person (the APS End User Licence file has no household identifier), scored on the APS donors. It fails when the evidence was not measured; when the model's out-of-fold log loss, pooled over the major groups by donor weight, is not at least minimum_log_loss_gain below the constant's (each group's training folds' class shares); when the blend's pooled log loss exceeds its better learner's by more than maximum_blend_log_loss_excess; when a major group's calibration slope falls outside calibration_slope_bounds or its Platt fit fell back to class rates; when the pooled gap between predicted and observed sub-major shares within the pay bands exceeds maximum_pay_band_share_gap, or within the regions maximum_region_share_gap; or when, in a major group resting on at least three FRS households, the FRS rows' expected sub-major shares miss the donors' by more than maximum_frame_share_gap (total variation), which bounds how far the FRS's own mix of age, sex, region, status, pay and section within a group moves the draw from the APS. The bounds sit wide of the stage measured on the APS April 2024 - March 2025 donors and FRS 2024-25 adults: a pooled log-loss gain of 0.37 (0.553 against 0.927), slopes of 0.95 to 1.01, a pay-band gap of 0.003, a region gap of 0.005, a log loss 0.006 below its better learner, and FRS rows' expected shares within 0.060 of the donors' (professional occupations; the other groups within 0.047). A population fact check: a synthetic smoke build records it without blocking, since a fixture of a few donors cannot fit the population's model." }, { "id": "uk_release_input_coverage", 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 b616d6cfe3..f9392a8808 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 @@ -472,7 +472,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -495,7 +495,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -518,7 +518,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -540,7 +540,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -570,7 +570,7 @@ "uc_is_in_gainful_self_employment" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "The FRS job record's company car answers through frs_spine's carriers (EXPBEN01, EXPBEN03, CARVAL, FUELTYP, CARCON, CARAMT), WAS round-8 company cars' list prices, and HMRC's 2024-25 company car recipients by CO2 band (Table 2A) and fuel (Table 2C), via the vendored facts", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" @@ -599,7 +599,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -619,7 +619,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -641,7 +641,7 @@ "required_mass_change_reason": "High-value home support divides every owner household in the top value stratum of its region into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "Microcosm structural operator (microcosm#1240 fix 1); no publisher input", "survey": "Family Resources Survey 2024-25 and SPI synthetic support, after the WAS wealth draw and the regional property uprating" @@ -662,7 +662,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -686,7 +686,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "6a2ba5e3e43c6d7936416552aadc716729b902dcac24b97093ae8ccf06cf8a8f", @@ -776,7 +776,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -803,7 +803,7 @@ "required_mass_change_reason": "ISA subscriptions per adult from HMRC's ISA tables on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "HMRC Individual Savings Account statistics Tables 9.4, 9.6 and 9.7 to 9.9, the cash ISA limit reduction impact note and Lifetime ISA Table 1a, via the vendored facts; Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "HMRC Annual savings statistics (September 2026 release); Wealth and Assets Survey round 8" @@ -873,7 +873,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "UK Data Service SN 9603 Living Costs and Food Survey 2024-25 (2nd edition) household/person tabs and the vendored Chronicle facts for NEED 2024 mean kWh, DESNZ Energy Trends and QEP average prices paid for calendar 2024, road-fuel outturn (DESNZ, HMRC, ONS Consumer Trends) and road fuel by vehicle type (DESNZ), ONS Consumer Trends household spending by COICOP division, the DfT VEH1103 licensed-car stock, NTS bus use, the NTS private cars (UK Data Service SN 5340, End User Licence; the vehicle and household tabs, survey years 2022-2024) for the zero-emission share by income fifth and the household-paid road-fuel mix, and the DfT and devolved bus finance tables and fares indices.", "survey": "Living Costs and Food Survey 2024-25" @@ -899,7 +899,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -919,7 +919,7 @@ "required_mass_change_reason": "Private-school attendance stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "policyengine-uk attends_private_school (the gov.simulation.private_school_vat attendance rates and factor), evaluated by the pinned engine", "survey": "policyengine-uk private-school attendance imputation, stored at the spine's weights" @@ -942,7 +942,7 @@ "property_finance_costs" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/property-rental-income-statistics", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Property Rental Income Statistics 2026 (tax year 2024-25)" @@ -963,7 +963,7 @@ "required_mass_change_reason": "Annual property purchases imputed on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "https://www.gov.uk/government/statistics/uk-stamp-tax-statistics", "survey": "HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected 11 March 2026), Tables 6b, 8a and 8b" @@ -986,7 +986,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "uk/high_value_home_value_knots.json, built by tools/build_uk_high_value_home_stock.py from PolicyEngine/chronicle#343's registrations", "survey": "HM Land Registry Price Paid latest sales uprated with the UK House Price Index, owner-weighted by region (the dense value node's knots, region level)" @@ -1010,7 +1010,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "MHCLG dwellings and the UK House Price Index regional average price averaged over the twelve months of calendar 2024 from the July 2026 full file, the frame's valuation basis, so the engine's annual uprating from 2024 projects the value once (microcosm#1240 fix 5).", "survey": "Public regional property reference" @@ -1038,7 +1038,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -1071,7 +1071,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -1094,7 +1094,7 @@ "student_loan_balance" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "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" @@ -1114,7 +1114,7 @@ "required_mass_change_reason": "Self-employed gross receipts stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "self_employment_income after the SPI income stage; HMRC's published gainers of the raise to GBP 3,000, about 400,000 taxpayers with a lower bill by about GBP 380 on average", "survey": "The self-employed's own profit on the final spine, and HMRC's policy paper on the Budget 2026 trading allowance raise (calibration)" @@ -1136,7 +1136,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -1175,7 +1175,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": "8c2d6d457f4feb95c49a762b1ba59e423f7117026d451bf0d2a87c7698e0aeb1", + "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index 72d46846c2..6f77439ea2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -2878,9 +2878,10 @@ { "artifacts": [], "grain": "person", - "notes": "Runs after company_cars, so the SPI-drawn rows' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region, falling back to the group and then to all adults where a cell holds fewer; so occupation and industry stay a pair that occurs. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", + "notes": "Runs after company_cars, so the SPI-drawn rows' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row's employment income is the tape's PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell's adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row's status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", "operations": [ { + "draw_support": "groups_frs_adults_of_the_rows_status_group_hold", "evidence": { "folds": 5, "pay_band_quantiles": [ @@ -2959,6 +2960,7 @@ ], "target": "soc2020_major_group" }, + "pay": "employment_income_or_the_tape_pay_of_spi_income_recipients", "rows": "spi_income_recipients_with_occupation_pay_or_profit", "seed": 0, "training_rows": "frs_channel_adults_with_occupation_positive_weight" @@ -2990,7 +2992,7 @@ } ], "grain": "person", - "notes": "Runs after spi_employment_shell, which settles every row's SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job's for people in employment (ILODEFR 1), the last job's otherwise, as the FRS records the main or last job. An employee's pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay (weekly pay times 52, arcsinh in the logit) and SIC 2007 section, the predictors both surveys record alike; a section the group's donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS's own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin's group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds' class shares; each group's calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows' expected sub-major shares against the donors' within each major group, with counts banded by the shared disclosure rules.", + "notes": "Runs after spi_employment_shell, which settles every row's SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job's for people in employment (ILODEFR 1), the last job's otherwise, as the FRS records the main or last job. An employee's pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay and SIC 2007 section, the predictors both surveys record alike. Pay is an employee's on both sides: the APS asks GRSSWK of employees only, so pay is weekly pay times 52 for an employee and zero for everyone else (the few on government employment and training programmes who report one included), and on the frame it is employment income for an employee, the tape's PAY for an SPI income recipient, and zero outside the employee status group; the logit reads it through arcsinh; a section the group's donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS's own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin's group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds' class shares; each group's calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows' expected sub-major shares against the donors' within each major group, with counts banded by the shared disclosure rules.", "operations": [ { "adult_age": 16, @@ -3117,6 +3119,7 @@ "solver": "lbfgs" }, "output": "soc2020_sub_major_group", + "pay": "employees_only_with_the_tape_pay_of_spi_income_recipients", "predictors": [ "age", "gender", 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 99e96c273c..6bdf18fdc2 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -2448,6 +2448,8 @@ stages: training_rows: frs_channel_adults_with_occupation_positive_weight rows: spi_income_recipients_with_occupation_pay_or_profit identity: person_id + pay: employment_income_or_the_tape_pay_of_spi_income_recipients + draw_support: groups_frs_adults_of_the_rows_status_group_hold seed: 0 occupation: target: soc2020_major_group @@ -2517,7 +2519,7 @@ stages: - soc2020_major_group - sic_industry_division - employment_sector - notes: 'Runs after company_cars, so the SPI-drawn rows'' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region, falling back to the group and then to all adults where a cell holds fewer; so occupation and industry stay a pair that occurs. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' + notes: 'Runs after company_cars, so the SPI-drawn rows'' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row''s employment income is the tape''s PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell''s adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row''s status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' - stage: aps_occupation survey: Annual Population Survey, April 2024 - March 2025 source: Office for National Statistics, Annual Population Survey, April 2024 - March 2025, UK Data Service SN 9408 (End User Licence), DOI 10.5255/UKDA-SN-9408-1; local licensed person tab; the SOC 2020 minor group of the main job, or of the last job for people not in work (microcosm#1490). @@ -2606,6 +2608,7 @@ stages: within: soc2020_major_group rows: people_with_a_major_group identity: person_source_id_or_spi_recipient_person_id + pay: employees_only_with_the_tape_pay_of_spi_income_recipients seed: 0 predictors: - age @@ -2656,7 +2659,7 @@ stages: - 65 outputs: - soc2020_sub_major_group - notes: 'Runs after spi_employment_shell, which settles every row''s SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job''s for people in employment (ILODEFR 1), the last job''s otherwise, as the FRS records the main or last job. An employee''s pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay (weekly pay times 52, arcsinh in the logit) and SIC 2007 section, the predictors both surveys record alike; a section the group''s donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS''s own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin''s group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds'' class shares; each group''s calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows'' expected sub-major shares against the donors'' within each major group, with counts banded by the shared disclosure rules.' + notes: 'Runs after spi_employment_shell, which settles every row''s SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job''s for people in employment (ILODEFR 1), the last job''s otherwise, as the FRS records the main or last job. An employee''s pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay and SIC 2007 section, the predictors both surveys record alike. Pay is an employee''s on both sides: the APS asks GRSSWK of employees only, so pay is weekly pay times 52 for an employee and zero for everyone else (the few on government employment and training programmes who report one included), and on the frame it is employment income for an employee, the tape''s PAY for an SPI income recipient, and zero outside the employee status group; the logit reads it through arcsinh; a section the group''s donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS''s own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin''s group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds'' class shares; each group''s calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows'' expected sub-major shares against the donors'' within each major group, with counts banded by the shared disclosure rules.' - stage: spi_housing_shell survey: Family Resources Survey 2024-25 source: Family Resources Survey 2024-25 base households' housing (tenure, dwelling type, bedrooms, council tax, housing costs and the housing-linked benefit reports), imputed onto the SPI support households from their own region, composition and post-SPI incomes. diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py index 26cb35b27b..71d713a53e 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py @@ -8,7 +8,9 @@ groups, ``microcosm.fit``'s categorical classifier (the equal mixture of a regularised boosted classifier and a spline logit) on age, sex, region, employment-status group, annual pay and SIC 2007 section, the predictors both -surveys record alike. A person with no major group keeps NONE. +surveys record alike. Pay is an employee's pay on both sides: the APS asks it of +employees only, so it is zero outside the employee status group, and an SPI +income recipient's is the tape's PAY. A person with no major group keeps NONE. The donors are the APS adults with a minor group whose pay is known: an employee's pay is asked in the income waves only, so an employee with pay @@ -87,6 +89,9 @@ STATUS_GROUP = "status_group" SECTION = "sic_section" PAY = "employment_income" +#: The SPI tape's own PAY, an SPI income recipient's pay. +SPI_PAY_COLUMN = "hmrc_spi_pay" +_EMPLOYEE = "EMPLOYEE" PREDICTORS = ("age", "gender", "region", STATUS_GROUP, PAY, SECTION) CATEGORICAL_PREDICTORS = ("gender", "region", STATUS_GROUP, SECTION) FRS_CHANNEL = "frs" @@ -150,6 +155,7 @@ "within": MAJOR_GROUP_COLUMN, "rows": "people_with_a_major_group", "identity": "person_source_id_or_spi_recipient_person_id", + "pay": "employees_only_with_the_tape_pay_of_spi_income_recipients", "seed": 0, "predictors": list(PREDICTORS), "categorical_predictors": list(CATEGORICAL_PREDICTORS), @@ -211,8 +217,11 @@ def clean_aps_occupation_table( A donor is an adult aged ``adult_age`` or over (``under_16`` status excluded) with a minor group: the main job's when in employment, the last job's otherwise. An employee needs a weekly pay of zero or more to stay, - since the income weight carries the employees asked; annual pay is the - weekly pay times ``pay_weeks`` where one is recorded and zero elsewhere. + since the income weight carries the employees asked. Pay is an employee's + gross weekly pay in the main job times ``pay_weeks``, and zero for everyone + else, as the frame's is: the APS asks it of employees only, and the few on + government employment and training programmes who report one are not + employees. Region, sex and status follow the declared codes, section codes 1 to 21 are the SIC 2007 sections in order, and anything else is "" (no section). Ages are capped at ``age_cap``, as the frame's are. @@ -283,7 +292,9 @@ def number(key: str) -> np.ndarray: "gender": sex[keep], "region": region[keep], STATUS_GROUP: status_group[keep], - PAY: np.where(pay >= 0, pay * float(cleaning["pay_weeks"]), 0.0)[keep], + PAY: np.where( + employee & (pay >= 0), pay * float(cleaning["pay_weeks"]), 0.0 + )[keep], SECTION: section[keep], MAJOR_GROUP_COLUMN: np.asarray( [UK_SOC2020_MAJOR_GROUP_OF_SUB_MAJOR_GROUP[g] for g in sub_major[keep]], @@ -336,9 +347,27 @@ def sub_major_model( def _frame_table( person: pd.DataFrame, household: pd.DataFrame, age_cap: float ) -> pd.DataFrame: - """Every person's predictors, major group, identities and channel.""" + """Every person's predictors, major group, identities and channel. + + Pay follows the donors' concept, an employee's pay: zero outside the + EMPLOYEE status group, and for an SPI income recipient the tape's PAY + (``hmrc_spi_pay``), since its ``employment_income`` also holds the tape's + EPB and TAXTERM. + """ households = household.set_index("household_id") by_person = person["person_household_id"].to_numpy() + recipient = person["person_is_spi_income_recipient"].astype(bool).to_numpy() + status_group = ( + person["employment_status"] + .astype(str) + .map(UK_OCCUPATION_STATUS_GROUP) + .to_numpy(dtype=object) + ) + pay = np.where( + recipient, + person[SPI_PAY_COLUMN].to_numpy(dtype=np.float64), + person[PAY].to_numpy(dtype=np.float64), + ) return pd.DataFrame( { "person_id": person["person_id"].to_numpy(), @@ -347,16 +376,11 @@ def _frame_table( "age": np.minimum(person["age"].to_numpy(dtype=np.float64), age_cap), "gender": person["gender"].astype(str).to_numpy(), "region": households["region"].astype(str).reindex(by_person).to_numpy(), - STATUS_GROUP: person["employment_status"] - .astype(str) - .map(UK_OCCUPATION_STATUS_GROUP) - .to_numpy(dtype=object), - PAY: person[PAY].to_numpy(dtype=np.float64), + STATUS_GROUP: status_group, + PAY: np.where(status_group == _EMPLOYEE, pay, 0.0), SECTION: uk_sic2007_sections(person["sic_industry_division"].to_numpy()), MAJOR_GROUP_COLUMN: person[MAJOR_GROUP_COLUMN].astype(str).to_numpy(), - "spi_income_recipient": person["person_is_spi_income_recipient"] - .astype(bool) - .to_numpy(), + "spi_income_recipient": recipient, "channel": households["household_support_channel"] .astype(str) .reindex(by_person) 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 0ab5d23ce4..4630d70dca 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/graph.py @@ -418,6 +418,7 @@ ("person", "sic_industry_division"), ("person", "soc2020_major_group"), ("person", "person_is_spi_income_recipient"), + ("person", "hmrc_spi_pay"), ("person", "person_source_id"), ("household", "region"), ("household", "household_support_channel"), diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py index 267b7ceb02..31229ca068 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/spi_employment_shell.py @@ -11,7 +11,11 @@ group from its age, sex, region, employment-status group and incomes, then copies an industry division and sector pair from an FRS adult with the drawn group, the same status group and the nearest age and incomes, so occupation and -industry stay a pair that occurs. +industry stay a pair that occurs and the sector one the row's status holds. A +row draws only among the groups that FRS adults of its own status group hold, +so such an adult always exists. A drawn row's pay is the tape's PAY +(``hmrc_spi_pay``): its ``employment_income`` also holds the tape's EPB and +TAXTERM, and termination pay says nothing of an occupation. The model is ``microcosm.fit``'s country-agnostic categorical classifier, the equal mixture of a regularised boosted classifier and a spline logit; the held- @@ -53,6 +57,7 @@ can_deal_folds, categorical_scores, donor_distance_features, + inverse_cdf_draw, keyed_nearest_donors, out_of_fold_proba, stratified_folds, @@ -107,6 +112,8 @@ "training_rows": "frs_channel_adults_with_occupation_positive_weight", "rows": "spi_income_recipients_with_occupation_pay_or_profit", "identity": "person_id", + "pay": "employment_income_or_the_tape_pay_of_spi_income_recipients", + "draw_support": "groups_frs_adults_of_the_rows_status_group_hold", "seed": 0, "occupation": { "target": OCCUPATION_COLUMN, @@ -210,9 +217,19 @@ def _pay_bands( def _person_table(person: pd.DataFrame, household: pd.DataFrame) -> pd.DataFrame: - """The predictors, target, keys and channel of every person.""" + """The predictors, target, keys and channel of every person. + + An SPI income recipient's ``employment_income`` predictor is the tape's + PAY: the column itself also holds the tape's EPB and TAXTERM (less the + company car benefits), which say nothing of an occupation. + """ households = household.set_index("household_id") by_person = person["person_household_id"].to_numpy() + pay = np.where( + person["person_is_spi_income_recipient"].astype(bool).to_numpy(), + person[SPI_PAY_COLUMN].to_numpy(dtype=np.float64), + person["employment_income"].to_numpy(dtype=np.float64), + ) table = pd.DataFrame( { "person_id": person["person_id"].to_numpy(), @@ -224,7 +241,7 @@ def _person_table(person: pd.DataFrame, household: pd.DataFrame) -> pd.DataFrame .astype(str) .map(UK_OCCUPATION_STATUS_GROUP) .to_numpy(dtype=object), - "employment_income": person["employment_income"].to_numpy(dtype=np.float64), + "employment_income": pay, "self_employment_income": person["self_employment_income"].to_numpy( dtype=np.float64 ), @@ -323,13 +340,12 @@ def _held_out_evidence( def _copy_cells(groups: np.ndarray, status: np.ndarray) -> list[np.ndarray]: - """The donor cells finest first: group and status, group, everyone.""" + """The one donor cell, group and status group: a copied sector is always one + the row's status holds, and a (group, section) pair one that occurs.""" return [ np.asarray( [f"{g}|{s}" for g, s in zip(groups, status, strict=True)], dtype=object - ), - np.asarray(groups, dtype=object), - np.zeros(len(groups), dtype=object), + ) ] @@ -370,17 +386,24 @@ def _held_out_industry( folds: np.ndarray, industry: Mapping[str, Any], seed: int, -) -> dict[str, float]: +) -> dict[str, object]: """Copy each fold's pairs from the other folds, given the adults' own groups. The gaps are the weighted mean, over major groups, of the total variation between the copied and observed SIC section shares, and of the absolute - public-sector share difference. + public-sector share difference. An adult whose group and status group no + adult of the other folds holds has no donor; it is left out and counted. """ copied = np.full(len(train), -1, dtype=np.int64) keys = train["person_id"].to_numpy() + cells = _copy_cells( + train[OCCUPATION_COLUMN].to_numpy(), train[STATUS_GROUP].to_numpy() + )[0] for fold in np.unique(folds): - test, rest = folds == fold, folds != fold + rest = folds != fold + test = (folds == fold) & np.isin(cells, cells[rest & (weights > 0)]) + if not test.any(): + continue positions, _ = _copy_donors( train.loc[test], train.loc[rest], @@ -401,7 +424,9 @@ def _held_out_industry( groups = train[OCCUPATION_COLUMN].to_numpy() total = section_gap = public_gap = 0.0 for group in np.unique(groups): - rows = groups == group + rows = (groups == group) & (copied >= 0) + if not rows.any(): + continue w = weights[rows] observed = pd.Series(w).groupby(section[rows]).sum() / w.sum() drawn = pd.Series(w).groupby(section[copied[rows]]).sum() / w.sum() @@ -420,12 +445,56 @@ def _held_out_industry( float(w @ public[rows] - w @ public[copied[rows]]) / w.sum() ) total += w.sum() + without = rounded_count(int((copied < 0).sum())) + if not total: + return {"status": "not_measured", "adults_without_a_donor": without} return { + "status": "measured", "section_share_gap_within_group": section_gap / total, "public_sector_share_gap_within_group": public_gap / total, + "adults_without_a_donor": without, } +def _draw_held_groups( + fitted, + recipients: pd.DataFrame, + train: pd.DataFrame, + train_weights: np.ndarray, + uniforms: np.ndarray, +) -> tuple[np.ndarray, np.ndarray]: + """Each row's group, drawn among the groups FRS adults of its status group hold. + + The other groups' probabilities go to zero and the rest are renormalised, + so the industry copy always has a donor of the row's own group and status + group. Rows that lose no probability draw exactly as the classifier gives. + Returns the drawn groups and which rows lost probability; a row whose status + group holds none of the groups refuses the stage. + """ + classes = fitted.classes_ + proba = fitted.predict_proba(recipients) + holders = train.loc[train_weights > 0] + status = recipients[STATUS_GROUP].to_numpy() + allowed = np.zeros(proba.shape, dtype=bool) + for status_group, groups in ( + holders.groupby(STATUS_GROUP)[OCCUPATION_COLUMN].unique().items() + ): + rows = np.flatnonzero(status == status_group) + allowed[np.ix_(rows, np.flatnonzero(np.isin(classes, groups)))] = True + restricted = (proba * ~allowed).sum(axis=1) > 0 + if restricted.any(): + kept = np.where(allowed[restricted], proba[restricted], 0.0) + total = kept.sum(axis=1) + if (total <= 0).any(): + raise ValueError( + f"{UK_SPI_EMPLOYMENT_SHELL_STAGE_NAME}: a drawn row's status group " + "holds none of the groups it could draw." + ) + proba = proba.copy() + proba[restricted] = kept / total[:, None] + return classes[inverse_cdf_draw(proba, uniforms)], restricted + + def _weighted_shares( values: np.ndarray, weights: np.ndarray, sources: np.ndarray ) -> dict[str, object]: @@ -540,15 +609,19 @@ def impute_spi_employment_shell( recipients["person_id"].to_numpy(), label=f"{stage} person_id" ) new_groups = np.asarray([], dtype=object) - copy_levels = np.asarray([], dtype=np.int64) + restricted = np.zeros(0, dtype=bool) + mismatched = 0 if len(recipients): - new_groups = fitted.predict_from_uniforms( + new_groups, restricted = _draw_held_groups( + fitted, recipients, + train, + train_weights, stable_identity_uniforms( keys, seed=seed, salt=f"{stage}:{OCCUPATION_COLUMN}" ), - )[OCCUPATION_COLUMN].to_numpy() - donor_positions, copy_levels = _copy_donors( + ) + donor_positions, _ = _copy_donors( recipients, train, new_groups, @@ -556,6 +629,12 @@ def impute_spi_employment_shell( stable_identity_uniforms(keys, seed=seed, salt=f"{stage}:industry"), operation["industry"], ) + mismatched = int( + ( + train[STATUS_GROUP].to_numpy()[donor_positions] + != recipients[STATUS_GROUP].to_numpy() + ).sum() + ) donor_rows = train_rows[donor_positions] person_out.loc[drawn, OCCUPATION_COLUMN] = new_groups for column in INDUSTRY_COLUMNS: @@ -585,10 +664,9 @@ def impute_spi_employment_shell( }, "industry_copy": { "neighbours": int(operation["industry"]["neighbours"]), - "levels": { - name: rounded_count(int((copy_levels == level).sum())) - for level, name in enumerate(("group_and_status", "group", "everyone")) - }, + "cell": "group_and_status_group", + "restricted_draws": rounded_count(int(restricted.sum())), + "donors_of_another_status_group": rounded_count(mismatched), "held_out": industry_held_out, }, } diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py index a48f7e3745..66ec7f34c4 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py @@ -143,7 +143,9 @@ def test_cleaning_keeps_adults_with_a_minor_group_and_known_pay(raw, donors) -> kept = raw.loc[expected] np.testing.assert_allclose( table["employment_income"].to_numpy(), - np.where(kept["GRSSWK"] >= 0, kept["GRSSWK"] * 52, 0.0), + np.where( + (kept["INECAC05"] == 1) & (kept["GRSSWK"] >= 0), kept["GRSSWK"] * 52, 0.0 + ), ) np.testing.assert_allclose( table["weight"].to_numpy(), @@ -175,6 +177,34 @@ def test_cleaning_keeps_adults_with_a_minor_group_and_known_pay(raw, donors) -> assert receipt["dropped"]["employee_pay_unknown"] not in (0, "<3") +def test_only_an_employees_pay_counts_among_donors(raw) -> None: + changed = raw.copy() + changed.loc[changed["INECAC05"] != 1, "GRSSWK"] = 400.0 + table, _ = clean_aps_occupation_table(changed) + others = table["status_group"] != "EMPLOYEE" + assert others.any() + assert (table.loc[others, "employment_income"] == 0).all() + + +def test_frame_pay_is_an_employees_and_a_recipients_is_the_tape_pay(tables) -> None: + from microcosm.build.uk_runtime.aps_occupation import _frame_table + + person, household, _ = tables + table = _frame_table(person, household, 80.0) + employee = (table["status_group"] == "EMPLOYEE").to_numpy() + recipient = person["person_is_spi_income_recipient"].to_numpy() + assert (~employee).any() and recipient.any() + assert (table.loc[~employee, "employment_income"] == 0).all() + np.testing.assert_allclose( + table.loc[recipient, "employment_income"], + person.loc[recipient, "hmrc_spi_pay"], + ) + rest = employee & ~recipient + np.testing.assert_allclose( + table.loc[rest, "employment_income"], person.loc[rest, "employment_income"] + ) + + def test_an_unknown_minor_group_is_refused(raw) -> None: broken = raw.copy() row = int(np.flatnonzero(broken["SC20MMN"] > 0)[0]) diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py index 3766f86157..1f63cb97ac 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_source_stages.py @@ -248,6 +248,18 @@ def test_age_tail_position_owns_the_only_later_age_rewrite_guard(self) -> None: assert "age" not in stage.outputs, stage.stage assert "age" not in stage.rewrites, stage.stage + def test_no_stage_after_aps_occupation_writes_an_occupation_group(self) -> None: + # aps_occupation checks that the sub-major group nests in the major + # group; that holds on the shipped frame only while no later stage + # writes either (microcosm#1490). The clones copy whole rows. + manifest = SourceManifest.from_mapping(_load_json(CANONICAL_SOURCE_STAGES)) + stages = list(manifest.stages) + names = [stage.stage for stage in stages] + for stage in stages[names.index("aps_occupation") + 1 :]: + for column in ("soc2020_major_group", "soc2020_sub_major_group"): + assert column not in stage.outputs, stage.stage + assert column not in stage.rewrites, stage.stage + def test_e8_block_is_final_and_all_stages_are_canonical(self) -> None: canonical = _load_json(CANONICAL_SOURCE_STAGES) names = [stage["stage"] for stage in canonical["stages"]] diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py index 72a4be813e..f4d218de3d 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_spi_employment_shell.py @@ -93,7 +93,7 @@ def test_rows_with_neither_an_occupation_nor_work_keep_none(tables, shell) -> No assert receipt["drawn"]["kept_no_occupation"] == "3-9" -def test_copied_industry_pairs_occur_among_donors_of_the_drawn_group( +def test_copied_pairs_come_from_donors_of_the_drawn_group_and_own_status( tables, shell ) -> None: person, household, weights = tables @@ -101,22 +101,68 @@ def test_copied_industry_pairs_occur_among_donors_of_the_drawn_group( frs = person["person_household_id"].isin( household.loc[household["household_support_channel"] == "frs", "household_id"] ) & (person["soc2020_major_group"] != "NONE") - donor_triples = set( + donors = set( zip( person.loc[frs, "soc2020_major_group"], + person.loc[frs, "employment_status"], person.loc[frs, "sic_industry_division"], person.loc[frs, "employment_sector"], strict=True, ) ) drawn = drawn_rows(person) - for triple in zip( + for copied in zip( person_out.loc[drawn, "soc2020_major_group"], + person_out.loc[drawn, "employment_status"], person_out.loc[drawn, "sic_industry_division"], person_out.loc[drawn, "employment_sector"], strict=True, ): - assert triple in donor_triples + assert copied in donors + + +def test_a_row_draws_only_groups_its_status_group_holds(tables) -> None: + person, household, weights = tables + changed = person.copy() + frs = changed["person_household_id"].isin( + household.loc[household["household_support_channel"] == "frs", "household_id"] + ) + managers = ( + changed["soc2020_major_group"] == "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS" + ) + self_employed = changed["employment_status"] == "FT_SELF_EMPLOYED" + changed.loc[frs & managers & self_employed, "employment_status"] = "FT_EMPLOYED" + out, receipt = impute_spi_employment_shell( + changed, household, weights, boosted_max_iter=60 + ) + drawn = drawn_rows(changed) & (changed["employment_status"] == "FT_SELF_EMPLOYED") + assert drawn.any() + assert not ( + out.loc[drawn, "soc2020_major_group"] + == "MANAGERS_DIRECTORS_AND_SENIOR_OFFICIALS" + ).any() + assert receipt["industry_copy"]["restricted_draws"] not in (0, "<3") + assert receipt["industry_copy"]["donors_of_another_status_group"] == 0 + + +def test_a_recipients_pay_predictor_is_the_tape_pay(tables) -> None: + from microcosm.build.uk_runtime.spi_employment_shell import _person_table + + person, household, _ = tables + changed = person.assign( + employment_income=person["employment_income"] + + 40_000.0 * person["person_is_spi_income_recipient"] + ) + table = _person_table(changed, household) + recipient = person["person_is_spi_income_recipient"].to_numpy() + np.testing.assert_allclose( + table.loc[recipient, "employment_income"], + person.loc[recipient, "hmrc_spi_pay"], + ) + np.testing.assert_allclose( + table.loc[~recipient, "employment_income"], + person.loc[~recipient, "employment_income"], + ) def test_draws_are_keyed_on_each_persons_id(tables, shell) -> None: @@ -139,11 +185,11 @@ def test_the_receipt_is_finite_json_with_banded_counts(shell) -> None: assert set(held_out["log_loss"]) == {"model", "boosted", "spline_logit", "marginal"} assert held_out["calibration_outcome"] == "cross_fitted" assert receipt["training"]["people"] == 1500 - assert set(receipt["industry_copy"]["levels"]) == { - "group_and_status", - "group", - "everyone", - } + copy = receipt["industry_copy"] + assert copy["cell"] == "group_and_status_group" + assert copy["donors_of_another_status_group"] == 0 + assert copy["restricted_draws"] == 0 + assert copy["held_out"]["status"] == "measured" for band in held_out["pay_bands"].values(): assert band["support"] in {"<3", "3-9", "10-29", "30+"} or band["support"] == 0 diff --git a/packages/microcosm-data/src/microcosm/data/contract.py b/packages/microcosm-data/src/microcosm/data/contract.py index ea20926535..06d101b887 100644 --- a/packages/microcosm-data/src/microcosm/data/contract.py +++ b/packages/microcosm-data/src/microcosm/data/contract.py @@ -478,10 +478,10 @@ def _is_hierarchy_diagnostics_version(value: object) -> bool: "97ec5dd9ee1f1809412c5a3513b9471963f359ae3a501871fb8ace91520820f8" ) _UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c790fadd40555b6062380b29b6c83f8c1cdec3ca6af5e1ad32fec71e0291d6f6" + "70eaed7fd3350ad6770725251836334e308067d5f4e8868ff61ea7f380e669ea" ) _UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "5fe0c71990495612dc6afc06215b66fb5e8b15558a4a6271416f59d3b3af5bcb" + "9f0c914ac30f383c3d0284e5889fe7e246333d3c1b5351015912bea0ef22aba1" ) #: Spec entry id -> the legacy gate name whose observable detail checks #: apply unchanged (the battery re-keys the report by entry id; the gate @@ -1018,7 +1018,7 @@ def _uk_line_cut_tag_re(release_id: str) -> re.Pattern[str] | None: _UK_CERTIFICATION_PART_DIGESTS: Mapping[str, Mapping[str, str]] = { "spine": { "gates_manifest_sha256": ( - "bb78d2be103399c9cf59eec229199ccab5aeddbc925db9c999944e473281125e" + "c552c77c2e6b0ca23323996820d9a2f53833fa0377eef4c607bc5fde32e939cf" ), "policy_sha256": ( "0a2635b7b22034ee1fa9b6574bc259805397171b367f4c7941509648704bf1bb" diff --git a/packages/microcosm-data/tests/engine_free/shared/test_contract.py b/packages/microcosm-data/tests/engine_free/shared/test_contract.py index 2531b81a13..0899a0f217 100644 --- a/packages/microcosm-data/tests/engine_free/shared/test_contract.py +++ b/packages/microcosm-data/tests/engine_free/shared/test_contract.py @@ -227,10 +227,10 @@ def _trusted_terminal_gate_signing_key(monkeypatch) -> None: "97ec5dd9ee1f1809412c5a3513b9471963f359ae3a501871fb8ace91520820f8" ) UK_GATE_BATTERY_GATES_MANIFEST_SHA256 = ( - "c790fadd40555b6062380b29b6c83f8c1cdec3ca6af5e1ad32fec71e0291d6f6" + "70eaed7fd3350ad6770725251836334e308067d5f4e8868ff61ea7f380e669ea" ) UK_GATE_BATTERY_SPEC_FINGERPRINT = ( - "5fe0c71990495612dc6afc06215b66fb5e8b15558a4a6271416f59d3b3af5bcb" + "9f0c914ac30f383c3d0284e5889fe7e246333d3c1b5351015912bea0ef22aba1" ) UK_GATE_BATTERY_DEGENERATE_EVIDENCE_SHA256 = ( "f246388de42654dd68dbbb40c42282001b5b0a8bf48976162bcb1199085cb1d3" diff --git a/test_support/microcosm_build/uk_aps_occupation.py b/test_support/microcosm_build/uk_aps_occupation.py index 27bcef3ae2..69c5162147 100644 --- a/test_support/microcosm_build/uk_aps_occupation.py +++ b/test_support/microcosm_build/uk_aps_occupation.py @@ -5,7 +5,8 @@ others below it. Everyone else draws a sub-major group at random. The frame's FRS households hold an adult and a partner with a major group and a child with none; each SPI household copies one, with its adult an SPI income recipient on -a high drawn pay and its partner and child exact copies of the twin's. +a high drawn pay (``hmrc_spi_pay``) and its partner and child exact copies of +the twin's. """ from __future__ import annotations @@ -118,6 +119,7 @@ def adults(status_draw: np.ndarray) -> pd.DataFrame: "sic_industry_division": rng.choice(_DIVISIONS, n_frs).astype(np.int64), "soc2020_major_group": rng.choice(majors, n_frs), "person_is_spi_income_recipient": False, + "hmrc_spi_pay": 0.0, } ) @@ -134,6 +136,7 @@ def adults(status_draw: np.ndarray) -> pd.DataFrame: "sic_industry_division": np.zeros(n_frs, dtype=np.int64), "soc2020_major_group": "NONE", "person_is_spi_income_recipient": False, + "hmrc_spi_pay": 0.0, } ) frs = pd.concat([adult, partner, child], ignore_index=True) @@ -149,7 +152,10 @@ def adults(status_draw: np.ndarray) -> pd.DataFrame: lead = copy.index[0] copy.loc[lead, "person_is_spi_income_recipient"] = True copy.loc[lead, "employment_status"] = "FT_EMPLOYED" - copy.loc[lead, "employment_income"] = rng.lognormal(12.3, 0.4) + # The tape's PAY, and an employment_income that adds benefits and + # termination pay to it. + copy.loc[lead, "hmrc_spi_pay"] = rng.lognormal(12.3, 0.4) + copy.loc[lead, "employment_income"] = copy.loc[lead, "hmrc_spi_pay"] + 5000.0 copies.append(copy) spi = pd.concat(copies, ignore_index=True) spi["person_id"] = 100_000 + np.arange(len(spi)) * 10 From 1625abc2abe2af6d23906401d17694c07086b7c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 17:26:18 +0000 Subject: [PATCH 6/7] Regenerate the H2 fixture and correct the employment shell's pay note (#1512) The charter-H2 fixture now follows the branch: - fixture.json carries the two new stages, and the synthetic APS donor sources/aps.csv (three people per sub-major group, under the codebook's names); - uk_spine.json carries the 54-stage graph. The fixture tool's legacy string audit lists soc2020_sub_major_group beside the major group, so it audits 31 cells, and NORMALIZATION.md follows. test_h2_uk_spine_parity and the integration smoke test pass. The employment shell's note no longer says the stage follows company_cars for its pay. A drawn row's pay predictor is the tape's PAY, which is cash pay without benefits in kind, as FRS pay is; the car benefits sit in EPB, which company_cars carves out of employment_income (Vahid's second review of #1512). The coverage manifest's source digests follow the note. Co-Authored-By: Claude Opus 5.5 --- .../uk/release_input_coverage_manifest.json | 50 ++-- .../src/microcosm/build/uk/source_stages.json | 2 +- .../src/microcosm/build/uk/spec/sources.yaml | 2 +- .../fixtures/parity/uk_spine/NORMALIZATION.md | 4 +- .../fixtures/parity/uk_spine/sources/aps.csv | 81 ++++++ .../parity/uk_spine/sources/fixture.json | 270 ++++++++++++++++++ .../fixtures/parity/uk_spine/uk_spine.json | 2 +- tools/graph_uk_spine_fixture.py | 8 +- 8 files changed, 386 insertions(+), 33 deletions(-) create mode 100644 packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/aps.csv 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 f9392a8808..9c4531afa5 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 @@ -472,7 +472,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -495,7 +495,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -518,7 +518,7 @@ "required_mass_change_reason": "Capital-gains residential split divides every household carrying liable gainers into arms weighted by the solved residential probabilities, one arm per subset of residential gainers; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative) on the amounts the Table 3 redraw placed" @@ -540,7 +540,7 @@ "required_mass_change_reason": "Capital-gains support split divides the wealthiest households of each HMRC Table 3 income band into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "HMRC Capital Gains Tax statistics, July 2026 release, Table 3 for 2024-25, via the vendored conditioning facts", "survey": "Family Resources Survey 2024-25, SPI synthetic support and HMRC Capital Gains Tax statistics Table 3 (2024-25 individuals by size of gain and taxable income)" @@ -570,7 +570,7 @@ "uc_is_in_gainful_self_employment" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "The FRS job record's company car answers through frs_spine's carriers (EXPBEN01, EXPBEN03, CARVAL, FUELTYP, CARCON, CARAMT), WAS round-8 company cars' list prices, and HMRC's 2024-25 company car recipients by CO2 band (Table 2A) and fuel (Table 2C), via the vendored facts", "survey": "Family Resources Survey 2024-25 job record; Wealth and Assets Survey round 8; HMRC Benefits in kind statistics (July 2026)" @@ -599,7 +599,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -619,7 +619,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -641,7 +641,7 @@ "required_mass_change_reason": "High-value home support divides every owner household in the top value stratum of its region into light copies at equal weight; every household's mass and the total household mass are conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "Microcosm structural operator (microcosm#1240 fix 1); no publisher input", "survey": "Family Resources Survey 2024-25 and SPI synthetic support, after the WAS wealth draw and the regional property uprating" @@ -662,7 +662,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "https://www.gov.uk/government/statistics/capital-gains-tax-statistics", "survey": "HMRC Capital Gains Tax statistics 2026 release, Table 8 (UK residential property disposals, 2024-25, administrative), Table 4.1 (individuals claiming Business Asset Disposal Relief or Investors' Relief by band of qualifying gain, 2024-25, administrative) and Table 7 (disposals, proceeds and gains by asset type, 2023-24, sample-based), vendored from the pinned Chronicle feed" @@ -686,7 +686,7 @@ "capital_gains" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "conditioning_resource": "hmrc_cgt_conditioning_facts.json", "conditioning_resource_sha256": "6a2ba5e3e43c6d7936416552aadc716729b902dcac24b97093ae8ccf06cf8a8f", @@ -776,7 +776,7 @@ "full_frs_tei_band_unavailable" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "hmrc_surface": "2023-24", "mapped_build_period": "2024", @@ -803,7 +803,7 @@ "required_mass_change_reason": "ISA subscriptions per adult from HMRC's ISA tables on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "HMRC Individual Savings Account statistics Tables 9.4, 9.6 and 9.7 to 9.9, the cash ISA limit reduction impact note and Lifetime ISA Table 1a, via the vendored facts; Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "HMRC Annual savings statistics (September 2026 release); Wealth and Assets Survey round 8" @@ -873,7 +873,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "UK Data Service SN 9603 Living Costs and Food Survey 2024-25 (2nd edition) household/person tabs and the vendored Chronicle facts for NEED 2024 mean kWh, DESNZ Energy Trends and QEP average prices paid for calendar 2024, road-fuel outturn (DESNZ, HMRC, ONS Consumer Trends) and road fuel by vehicle type (DESNZ), ONS Consumer Trends household spending by COICOP division, the DfT VEH1103 licensed-car stock, NTS bus use, the NTS private cars (UK Data Service SN 5340, End User Licence; the vehicle and household tabs, survey years 2022-2024) for the zero-emission share by income fifth and the household-paid road-fuel mix, and the DfT and devolved bus finance tables and fares indices.", "survey": "Living Costs and Food Survey 2024-25" @@ -899,7 +899,7 @@ "required_mass_change_reason": "NTS bus-travel imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -919,7 +919,7 @@ "required_mass_change_reason": "Private-school attendance stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "policyengine-uk attends_private_school (the gov.simulation.private_school_vat attendance rates and factor), evaluated by the pinned engine", "survey": "policyengine-uk private-school attendance imputation, stored at the spine's weights" @@ -942,7 +942,7 @@ "property_finance_costs" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "https://www.gov.uk/government/statistics/property-rental-income-statistics", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Property Rental Income Statistics 2026 (tax year 2024-25)" @@ -963,7 +963,7 @@ "required_mass_change_reason": "Annual property purchases imputed on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "https://www.gov.uk/government/statistics/uk-stamp-tax-statistics", "survey": "HMRC Annual Stamp Tax Statistics 2024 to 2025 (corrected 11 March 2026), Tables 6b, 8a and 8b" @@ -986,7 +986,7 @@ "property_wealth" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "uk/high_value_home_value_knots.json, built by tools/build_uk_high_value_home_stock.py from PolicyEngine/chronicle#343's registrations", "survey": "HM Land Registry Price Paid latest sales uprated with the UK House Price Index, owner-weighted by region (the dense value node's knots, region level)" @@ -1010,7 +1010,7 @@ "non_residential_property_value" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "MHCLG dwellings and the UK House Price Index regional average price averaged over the twelve months of calendar 2024 from the July 2026 full file, the frame's valuation basis, so the engine's annual uprating from 2024 projects the value once (microcosm#1240 fix 5).", "survey": "Public regional property reference" @@ -1038,7 +1038,7 @@ "employment_income" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -1071,7 +1071,7 @@ "household_source_id" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "Reserved SPI support households for the HMRC Table 2.5 total-income bands from GBP 200,000, stacked at the published band taxpayer count over the donors per band (PolicyEngine/chronicle#280 lane).", "survey": "Survey of Personal Incomes Public Use Tape 2022-23 and HMRC Income Tax liabilities statistics July 2026 Table 2.5" @@ -1094,7 +1094,7 @@ "student_loan_balance" ], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "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" @@ -1114,7 +1114,7 @@ "required_mass_change_reason": "Self-employed gross receipts stored on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "self_employment_income after the SPI income stage; HMRC's published gainers of the raise to GBP 3,000, about 400,000 taxpayers with a lower bill by about GBP 380 on average", "survey": "The self-employed's own profit on the final spine, and HMRC's policy paper on the Budget 2026 trading allowance raise (calibration)" @@ -1136,7 +1136,7 @@ "required_mass_change_reason": "WAS Lifetime ISA imputation on the source spine: household weights pass through unchanged and total household mass is conserved.", "rewrites": [], "source_manifest": "source_stages.json", - "source_manifest_sha256": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed round-8 person and household tabs (interviews April 2020 to March 2022, Great Britain).", "survey": "Wealth and Assets Survey round 8" @@ -1175,7 +1175,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": "7a01b068a0df759258a144de071d3238e77056caa3fb71596c09e534a872a7f4", + "source_manifest_sha256": "b9c285e3aa429c769d149cef14b8ebcacde4d170511f4be172979d2f47abd743", "source_vintages": { "source": "Office for National Statistics Wealth and Assets Survey, UK Data Service SN 7215, DOI 10.5255/UKDA-SN-7215-20; local licensed 2006-22 household tab.", "survey": "Wealth and Assets Survey round 8" diff --git a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json index 6f77439ea2..7bb19336ff 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/source_stages.json +++ b/packages/microcosm-build/src/microcosm/build/uk/source_stages.json @@ -2878,7 +2878,7 @@ { "artifacts": [], "grain": "person", - "notes": "Runs after company_cars, so the SPI-drawn rows' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row's employment income is the tape's PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell's adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row's status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", + "notes": "Runs after company_cars and before spi_housing_shell (microcosm#1490). A drawn row's pay predictor is the tape's PAY (hmrc_spi_pay), cash pay without benefits in kind, as FRS pay is: the car benefits sit in the tape's EPB, which company_cars carves out of employment_income, and company_cars leaves PAY alone. The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row's employment income is the tape's PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell's adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row's status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", "operations": [ { "draw_support": "groups_frs_adults_of_the_rows_status_group_hold", 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 6bdf18fdc2..d85607ecf6 100644 --- a/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml +++ b/packages/microcosm-build/src/microcosm/build/uk/spec/sources.yaml @@ -2519,7 +2519,7 @@ stages: - soc2020_major_group - sic_industry_division - employment_sector - notes: 'Runs after company_cars, so the SPI-drawn rows'' pay is net of car benefits as FRS pay is, and before spi_housing_shell (microcosm#1490). The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row''s employment income is the tape''s PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell''s adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row''s status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' + notes: 'Runs after company_cars and before spi_housing_shell (microcosm#1490). A drawn row''s pay predictor is the tape''s PAY (hmrc_spi_pay), cash pay without benefits in kind, as FRS pay is: the car benefits sit in the tape''s EPB, which company_cars carves out of employment_income, and company_cars leaves PAY alone. The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin''s SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin''s pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape''s own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows'' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row''s employment income is the tape''s PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin''s and are left out. The classifier is microcosm.fit''s CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell''s adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row''s status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds'' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy''s section and public-sector gaps within groups; and the fit''s iterations, with counts banded by the shared disclosure rules.' - stage: aps_occupation survey: Annual Population Survey, April 2024 - March 2025 source: Office for National Statistics, Annual Population Survey, April 2024 - March 2025, UK Data Service SN 9408 (End User Licence), DOI 10.5255/UKDA-SN-9408-1; local licensed person tab; the SOC 2020 minor group of the main job, or of the last job for people not in work (microcosm#1490). diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md index 59bc77cc82..b473ed6482 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/NORMALIZATION.md @@ -1,6 +1,6 @@ # UK spine parity string normalization -The unchanged legacy transforms retain these 30 textual table columns as +The unchanged legacy transforms retain these 31 textual table columns as pandas `object`. The frozen graph dtype token `string` is specified by interface-freeze amendment 10 as pandas `StringDtype(storage="python")`. Before computing the legacy oracle's `uk_frame_content_identity` (live, @@ -8,6 +8,6 @@ in `legacy_oracle_identity`), exactly this audited surface is cast to that dtype. No values, row order, column order, weights, strata, mass records, or metadata change. -- `person`: `gender`, `marital_status`, `employment_status`, `employment_sector`, `soc2020_major_group`, `aa_category`, `dla_sc_category`, `dla_m_category`, `pip_m_category`, `pip_dl_category`, `current_education`, `highest_education`, `person_support_channel`, `student_loan_plan`, `relationship_to_head`, `ons_family_role`, `capital_gains_asset_type`, `company_car_fuel_type`, `car_fuel_type`, `car_first_registration_date` +- `person`: `gender`, `marital_status`, `employment_status`, `employment_sector`, `soc2020_major_group`, `soc2020_sub_major_group`, `aa_category`, `dla_sc_category`, `dla_m_category`, `pip_m_category`, `pip_dl_category`, `current_education`, `highest_education`, `person_support_channel`, `student_loan_plan`, `relationship_to_head`, `ons_family_role`, `capital_gains_asset_type`, `company_car_fuel_type`, `car_fuel_type`, `car_first_registration_date` - `benunit`: `benunit_support_channel`, `uc_deduction_combination` - `household`: `region`, `tenure_type`, `accommodation_type`, `council_tax_band`, `brma`, `household_support_channel`, `source_household_key`, `ons_household_type` diff --git a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/aps.csv b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/aps.csv new file mode 100644 index 0000000000..e082dc96fd --- /dev/null +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/sources/aps.csv @@ -0,0 +1,81 @@ +AGE,SEX,GOVTOF,ILODEFR,INECAC05,SC20MMN,SC20LMN,GRSSWK,PWTA22,PIWTA22,INDS07M,INDS07L +20,1,1,1,1,111,-9,300,500,900,1,-9 +21,2,2,1,2,111,-9,-9,501,-9,2,-9 +22,1,3,3,16,-9,111,-9,502,-9,-9,3 +23,2,4,1,1,121,-9,375,503,903,4,-9 +24,1,5,1,2,121,-9,-9,504,-9,5,-9 +25,2,6,3,16,-9,121,-9,505,-9,-9,6 +26,1,7,1,1,211,-9,450,506,906,7,-9 +27,2,8,1,2,211,-9,-9,507,-9,8,-9 +28,1,9,3,16,-9,211,-9,508,-9,-9,9 +29,2,10,1,1,221,-9,525,509,909,10,-9 +30,1,11,1,2,221,-9,-9,510,-9,11,-9 +31,2,12,3,16,-9,221,-9,511,-9,-9,12 +32,1,13,1,1,231,-9,600,512,912,13,-9 +33,2,1,1,2,231,-9,-9,513,-9,14,-9 +34,1,2,3,16,-9,231,-9,514,-9,-9,15 +35,2,3,1,1,241,-9,675,515,915,16,-9 +36,1,4,1,2,241,-9,-9,516,-9,17,-9 +37,2,5,3,16,-9,241,-9,517,-9,-9,18 +38,1,6,1,1,311,-9,750,518,918,19,-9 +39,2,7,1,2,311,-9,-9,519,-9,20,-9 +40,1,8,3,16,-9,311,-9,520,-9,-9,1 +41,2,9,1,1,321,-9,825,521,921,2,-9 +42,1,10,1,2,321,-9,-9,522,-9,3,-9 +43,2,11,3,16,-9,321,-9,523,-9,-9,4 +44,1,12,1,1,331,-9,900,524,924,5,-9 +45,2,13,1,2,331,-9,-9,525,-9,6,-9 +46,1,1,3,16,-9,331,-9,526,-9,-9,7 +47,2,2,1,1,341,-9,975,527,927,8,-9 +48,1,3,1,2,341,-9,-9,528,-9,9,-9 +49,2,4,3,16,-9,341,-9,529,-9,-9,10 +50,1,5,1,1,351,-9,1050,530,930,11,-9 +51,2,6,1,2,351,-9,-9,531,-9,12,-9 +52,1,7,3,16,-9,351,-9,532,-9,-9,13 +53,2,8,1,1,411,-9,1125,533,933,14,-9 +54,1,9,1,2,411,-9,-9,534,-9,15,-9 +55,2,10,3,16,-9,411,-9,535,-9,-9,16 +56,1,11,1,1,421,-9,1200,536,936,17,-9 +57,2,12,1,2,421,-9,-9,537,-9,18,-9 +58,1,13,3,16,-9,421,-9,538,-9,-9,19 +59,2,1,1,1,511,-9,1275,539,939,20,-9 +60,1,2,1,2,511,-9,-9,540,-9,1,-9 +61,2,3,3,16,-9,511,-9,541,-9,-9,2 +62,1,4,1,1,521,-9,1350,542,942,3,-9 +63,2,5,1,2,521,-9,-9,543,-9,4,-9 +64,1,6,3,16,-9,521,-9,544,-9,-9,5 +65,2,7,1,1,531,-9,1425,545,945,6,-9 +66,1,8,1,2,531,-9,-9,546,-9,7,-9 +67,2,9,3,16,-9,531,-9,547,-9,-9,8 +68,1,10,1,1,541,-9,1500,548,948,9,-9 +69,2,11,1,2,541,-9,-9,549,-9,10,-9 +70,1,12,3,16,-9,541,-9,550,-9,-9,11 +71,2,13,1,1,611,-9,1575,551,951,12,-9 +72,1,1,1,2,611,-9,-9,552,-9,13,-9 +73,2,2,3,16,-9,611,-9,553,-9,-9,14 +74,1,3,1,1,621,-9,1650,554,954,15,-9 +75,2,4,1,2,621,-9,-9,555,-9,16,-9 +76,1,5,3,16,-9,621,-9,556,-9,-9,17 +77,2,6,1,1,631,-9,1725,557,957,18,-9 +78,1,7,1,2,631,-9,-9,558,-9,19,-9 +79,2,8,3,16,-9,631,-9,559,-9,-9,20 +20,1,9,1,1,711,-9,1800,560,960,1,-9 +21,2,10,1,2,711,-9,-9,561,-9,2,-9 +22,1,11,3,16,-9,711,-9,562,-9,-9,3 +23,2,12,1,1,721,-9,1875,563,963,4,-9 +24,1,13,1,2,721,-9,-9,564,-9,5,-9 +25,2,1,3,16,-9,721,-9,565,-9,-9,6 +26,1,2,1,1,811,-9,1950,566,966,7,-9 +27,2,3,1,2,811,-9,-9,567,-9,8,-9 +28,1,4,3,16,-9,811,-9,568,-9,-9,9 +29,2,5,1,1,821,-9,2025,569,969,10,-9 +30,1,6,1,2,821,-9,-9,570,-9,11,-9 +31,2,7,3,16,-9,821,-9,571,-9,-9,12 +32,1,8,1,1,911,-9,2100,572,972,13,-9 +33,2,9,1,2,911,-9,-9,573,-9,14,-9 +34,1,10,3,16,-9,911,-9,574,-9,-9,15 +35,2,11,1,1,921,-9,2175,575,975,16,-9 +36,1,12,1,2,921,-9,-9,576,-9,17,-9 +37,2,13,3,16,-9,921,-9,577,-9,-9,18 +15,1,1,1,26,111,-9,300,500,900,1,-9 +20,1,1,1,1,111,-9,-8,500,-9,1,-9 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 d9b385a0c4..7b26974ab5 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 @@ -21,6 +21,7 @@ }, "description": "Data-only inputs for reconstructing the same 31 current UK stage transform classes used by the legacy StagePlan oracle.", "inputs": { + "aps": "aps.csv", "cgt_asset_type_facts": "cgt_asset_type_facts.json", "cgt_distribution": "cgt_distribution.json", "etb": "etb.csv", @@ -95,6 +96,173 @@ "stage": "age_tail", "survey": "Family Resources Survey 2024-25 and ONS mid-year population estimates" }, + "aps_occupation": { + "artifacts": [ + { + "access": "private_local_input", + "doi": "10.5255/UKDA-SN-9408-1", + "filename": "apsp_a24m25_eul_pwta22.tab", + "kind": "private_microdata", + "locator": "caller-supplied local input", + "role": "aps_person_tab", + "runtime_sha256_required": true, + "sha256": "8b4327d3c331b18cf1b1e16485489645f5f57562cca0555315a520c1592b56af", + "size_bytes": 257997154, + "ukds_study_number": 9408 + } + ], + "grain": "person", + "nonnegative_outputs": [], + "notes": "Runs after spi_employment_shell, which settles every row's SOC 2020 major group and SIC 2007 division, and before any later stage copies households (microcosm#1490). The FRS codes the major group only; the APS codes the minor group, whose first two digits are the sub-major group. The donors are the APS adults (16 and over, not under-16 status) with a minor group: the main job's for people in employment (ILODEFR 1), the last job's otherwise, as the FRS records the main or last job. An employee's pay (GRSSWK, gross weekly pay in the main job) is asked in the income waves only, so employees without one leave the donors and those with one carry the income weight PIWTA22; everyone else carries the person weight PWTA22. Each major group gets its own model over its sub-major groups: microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features, on age (capped at 80, the FRS top code), sex, region, employment-status group (employee, self-employed, retired, other), annual pay and SIC 2007 section, the predictors both surveys record alike. Pay is an employee's on both sides: the APS asks GRSSWK of employees only, so pay is weekly pay times 52 for an employee and zero for everyone else (the few on government employment and training programmes who report one included), and on the frame it is employment income for an employee, the tape's PAY for an SPI income recipient, and zero outside the employee status group; the logit reads it through arcsinh; a section the group's donors never hold sets no indicator, and the receipt counts the households that held one. That blend and predictor set held out best on the APS (five stratified folds by person; adding full or part time, usual hours and qualification gained less than 0.02 nats), and the same model trained on the APS scored the FRS's own major groups within 0.01 nats of a model trained on the FRS. A person with no major group keeps NONE. Draws read uniforms keyed on person_source_id, so a copy draws its FRS twin's group, except for the SPI income recipients, whose incomes and occupation the SPI stages drew and who key on their own person_id. Codes verified 2026-11-04 against the deposited SN 9408 data dictionary (apsp_a24m25_eul_pwta22_ukda_data_dictionary.rtf): SC20MMN and SC20LMN are minor groups 111 to 926 with -9 and -8 missing; ILODEFR 1 is in employment; INECAC05 1 is employee, 2 self-employed, 16 and 24 retired, 26 under 16, and every other code is grouped as other; SEX 1 male, 2 female; GOVTOF 1 to 13 are the government office regions with Merseyside (3) part of the North West, and agree with GOR9DCENSUS2021 on every record; INDS07M and INDS07L 1 to 21 are SIC 2007 sections A to U; GRSSWK, PWTA22 and PIWTA22 use -9 and -8 for missing. The receipt records the donors by major group and the held-out evidence per major group and pooled: log loss of the model, each learner and the training folds' class shares; each group's calibration slope; and sub-major share gaps within pay bands, regions, age bands and status groups; then the FRS rows' expected sub-major shares against the donors' within each major group, with counts banded by the shared disclosure rules.", + "operations": [ + { + "adult_age": 16, + "age_cap": 80, + "codes": { + "employee": 1, + "in_employment": 1, + "other_status_group": "OTHER", + "region": { + "1": "NORTH_EAST", + "10": "SOUTH_WEST", + "11": "WALES", + "12": "SCOTLAND", + "13": "NORTHERN_IRELAND", + "2": "NORTH_WEST", + "3": "NORTH_WEST", + "4": "YORKSHIRE", + "5": "EAST_MIDLANDS", + "6": "WEST_MIDLANDS", + "7": "EAST_OF_ENGLAND", + "8": "LONDON", + "9": "SOUTH_EAST" + }, + "sections": [ + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U" + ], + "sex": { + "1": "MALE", + "2": "FEMALE" + }, + "status_group": { + "1": "EMPLOYEE", + "16": "RETIRED", + "2": "SELF_EMPLOYED", + "24": "RETIRED" + }, + "under_16": 26 + }, + "columns": { + "age": "AGE", + "economic_activity": "ILODEFR", + "income_weight": "PIWTA22", + "last_minor_group": "SC20LMN", + "last_section": "INDS07L", + "main_minor_group": "SC20MMN", + "main_section": "INDS07M", + "person_weight": "PWTA22", + "region": "GOVTOF", + "sex": "SEX", + "status": "INECAC05", + "weekly_pay": "GRSSWK" + }, + "kind": "clean_aps_occupation_table", + "lowercase_columns": true, + "pay_weeks": 52 + }, + { + "arcsinh_columns": [ + "employment_income" + ], + "arcsinh_scale": 1000, + "boosted": { + "early_stopping": true, + "l2_regularization": 1, + "learning_rate": 0.05, + "max_iter": 500, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "n_iter_no_change": 20, + "validation_fraction": 0.2 + }, + "boosted_weight": 0.5, + "categorical_predictors": [ + "gender", + "region", + "status_group", + "sic_section" + ], + "evidence": { + "age_band_edges": [ + 25, + 35, + 45, + 55, + 65 + ], + "folds": 5, + "grouping": "person", + "pay_band_quantiles": [ + 0.5, + 0.8, + 0.9 + ] + }, + "identity": "person_source_id_or_spi_recipient_person_id", + "kind": "impute_soc2020_sub_major_group", + "logit": { + "degree": 3, + "extrapolation": "constant", + "knots": "quantile", + "max_iter": 3000, + "n_knots": 6, + "penalty_c": 1, + "solver": "lbfgs" + }, + "output": "soc2020_sub_major_group", + "pay": "employees_only_with_the_tape_pay_of_spi_income_recipients", + "predictors": [ + "age", + "gender", + "region", + "status_group", + "employment_income", + "sic_section" + ], + "rows": "people_with_a_major_group", + "seed": 0, + "unseen_categories": "ignore", + "within": "soc2020_major_group" + } + ], + "outputs": [ + "soc2020_sub_major_group" + ], + "rewrites": [], + "source": "Office for National Statistics, Annual Population Survey, April 2024 - March 2025, UK Data Service SN 9408 (End User Licence), DOI 10.5255/UKDA-SN-9408-1; local licensed person tab; the SOC 2020 minor group of the main job, or of the last job for people not in work (microcosm#1490).", + "stage": "aps_occupation", + "survey": "Annual Population Survey, April 2024 - March 2025" + }, "carers_allowance_take_up": { "artifacts": [], "grain": "person", @@ -6817,6 +6985,108 @@ "stage": "spi_benefit_coherence", "survey": "Family Resources Survey 2024-25" }, + "spi_employment_shell": { + "artifacts": [], + "grain": "person", + "nonnegative_outputs": [], + "notes": "Runs after company_cars and before spi_housing_shell (microcosm#1490). A drawn row's pay predictor is the tape's PAY (hmrc_spi_pay), cash pay without benefits in kind, as FRS pay is: the car benefits sit in the tape's EPB, which company_cars carves out of employment_income, and company_cars leaves PAY alone. The support copies and income band donors are whole FRS households, so a drawn row (person_is_spi_income_recipient) kept its twin's SOC 2020 major group, SIC 2007 division and sector, all chosen with the twin's pay, not the incomes it drew. The stage redraws the major group of every drawn row whose twin had an occupation, or which drew pay (the tape's own PAY) or a profit; a drawn row with neither keeps NONE, and FRS rows and undrawn copies are untouched. It trains on the FRS rows' adults aged 16 and over with an occupation and positive household weight, weighted by household weight, and conditions on age, sex, region, employment-status group (employee, self-employed, retired, other) and employment, self-employment, investment (savings interest plus dividends) and private pension income, which the drawn rows hold of their own; a drawn row's employment income is the tape's PAY (hmrc_spi_pay), since its employment_income also holds EPB and TAXTERM, and termination pay says nothing of an occupation. Industry, hours and qualification are the twin's and are left out. The classifier is microcosm.fit's CategoricalClassifier, the equal mixture of a regularised gradient-boosted classifier and a multinomial logit on spline features (arcsinh incomes), the blend that held out best on FRS 2024-25 (log loss, calibration slope and occupation shares within pay bands and status groups). Each drawn row then copies the SIC division and sector of an FRS adult with the drawn group and the same status group, chosen by household weight among the 50 nearest on age rank, income presence and ranks and region (all of the cell's adults where it holds fewer); so occupation and industry stay a pair that occurs, and the sector is one the row's status group holds. A row draws only among the groups FRS adults of its own status group hold, so such an adult always exists; the receipt counts the rows whose draw that restricts, which on FRS 2024-25 at full scale is none. Every draw reads uniforms keyed on person_id. The receipt records the held-out evidence on five folds dealing whole households: log loss of the model, each learner and the training folds' class shares; the calibration slope; occupation-share gaps within pay bands and status groups; the industry copy's section and public-sector gaps within groups; and the fit's iterations, with counts banded by the shared disclosure rules.", + "operations": [ + { + "draw_support": "groups_frs_adults_of_the_rows_status_group_hold", + "evidence": { + "folds": 5, + "pay_band_quantiles": [ + 0.5, + 0.8, + 0.9, + 0.95, + 0.99 + ] + }, + "identity": "person_id", + "industry": { + "cells": [ + "soc2020_major_group", + "status_group" + ], + "columns": [ + "sic_industry_division", + "employment_sector" + ], + "neighbours": 50, + "presence_rank_columns": [ + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "rank_columns": [ + "age" + ], + "region_scale": 0.3 + }, + "kind": "impute_spi_employment_shell", + "occupation": { + "arcsinh_columns": [ + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "arcsinh_scale": 1000, + "boosted": { + "early_stopping": true, + "l2_regularization": 1, + "learning_rate": 0.05, + "max_iter": 500, + "max_leaf_nodes": 15, + "min_samples_leaf": 40, + "n_iter_no_change": 20, + "validation_fraction": 0.2 + }, + "boosted_weight": 0.5, + "categorical_predictors": [ + "gender", + "region", + "status_group" + ], + "logit": { + "degree": 3, + "extrapolation": "constant", + "knots": "quantile", + "max_iter": 3000, + "n_knots": 6, + "penalty_c": 1, + "solver": "lbfgs" + }, + "predictors": [ + "age", + "gender", + "region", + "status_group", + "employment_income", + "self_employment_income", + "investment_income", + "private_pension_income" + ], + "target": "soc2020_major_group" + }, + "pay": "employment_income_or_the_tape_pay_of_spi_income_recipients", + "rows": "spi_income_recipients_with_occupation_pay_or_profit", + "seed": 0, + "training_rows": "frs_channel_adults_with_occupation_positive_weight" + } + ], + "outputs": [], + "rewrites": [ + "soc2020_major_group", + "sic_industry_division", + "employment_sector" + ], + "source": "Family Resources Survey 2024-25 adults' SOC 2020 major group, SIC 2007 division and sector, redrawn onto the SPI-drawn rows from their own incomes (microcosm#1490).", + "stage": "spi_employment_shell", + "survey": "Family Resources Survey 2024-25" + }, "spi_housing_shell": { "artifacts": [], "grain": "household", 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 9724b03bdf..9e804885c7 100644 --- a/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json +++ b/packages/microcosm-graph/tests/fixtures/parity/uk_spine/uk_spine.json @@ -1 +1 @@ -{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","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":"frs_care_hours_in_household","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_blind","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"annuity_and_trust_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"individual_savings_account_interest_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":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"spousal_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":"statutory_paternity_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":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_price_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_fuel_code","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_private_fuel","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_contribution","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":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"widowed_parents_allowance_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":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"879fdd6e1e5832b94af4259b1028f852470bbe2c3ab19b61ce5f92a2e9c12ec4","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","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_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":"months_since_last_birthday","dtype":"float64","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":"frs_care_hours_in_household","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_blind","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":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","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":"annuity_and_trust_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"individual_savings_account_interest_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":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"spousal_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":"statutory_paternity_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":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_price_band","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_fuel_code","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_private_fuel","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_contribution","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":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"liable_for_share_of_household_rent","dtype":"bool","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","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_looked_after_by_local_authority","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"child_limit_non_parental_caring_exception","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"ae32bf855753d3b7505e54a18532b1b53a04b6beda764cc09ad09462cf130085","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"ddbefaf05b44788d794a6e4b0e8926c14318d66e50d2f11f50ca549538bbf60c","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","sic_industry_division"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"06804f54c12d25f2afcb31eec27789802f663cb42689a932dc32f3ba5fc05fff","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_outstanding_student_loan","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_left_full_time_education","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"592ddc77703f19bb3e1d48b6aecffc98b4e2abd3379db84a06e011bde4fa5549","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","is_uc_claimant","months_since_last_birthday","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"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"78aec80408c50455b37308e5a977fb70df3ecf915d6c1e8f80715ad9b58e62cf","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employment_income","employment_status","max_free_entitlement_hours_used"],"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"},{"column":"is_apprentice","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"112c502d702c640dedbc2dca7d1cfe5ae43e0f0e3ba6acfe49c738dbbfb7e693","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"4285376b37299d375ed583b7f6b1747bd8b7cb1c8c0d19a36481156b5314a854","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","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"6b2e0264fbac47dae5e1fc4fa9e980c5c2caf7f12f165129649a559f3ad7a154","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_annual_income_spells.","id":"frs_annual_income_spells","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employer_pension_contributions","employment_income","gender","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_annual_income_spells@1","mass":"conserve","outputs":[{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_annual_income_spells","stage_contract_sha256":"1dbdd0c9a6602be53b5527435d093a934218936d550da8b720973fc745c997ca","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"4754ace499836c44b00c1c53a9ef5fd686d3a29108d0d546d7a11dcc37ee8807","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","rent_paid_as_boarder","rent_paid_as_lodger","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"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":"property_finance_costs","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":"individual_savings_account_interest_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":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","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":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"annuity_and_trust_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"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_is_spi_income_recipient","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"481cec216d5edea741ff81c3cf939b521c0b89286ca6a67795862c6358118039","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before company_cars rewrites.","id":"company_cars.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage company_cars.","id":"company_cars","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.stage.company_cars@1","mass":"conserve","outputs":[{"column":"company_car_list_price","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_co2_emissions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_fuel_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_electric_range","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_capital_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_private_fuel_provided","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"company_cars","stage_contract_sha256":"a4e0348ecb76f8550486df0682d4f2d6b7d2dee3038f5bbcf6bd0a347b7dfa6a","time_period":"2024"},"population":"company_cars.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"company_cars.boundary","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","individual_savings_account_interest_income","is_household_head","other_investment_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported","uc_is_in_gainful_self_employment"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"9a76a02ceddb2cd85819f57cd33feb44d645800ce963d0b18bad0f6de808fd81","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided"],"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"},{"column":"directly_held_shares","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"unit_and_investment_trusts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"4c0bcaabf3695a75ec7e69d99b6b8c90570fd345067d77f1ea315f5508a88962","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"bf0389b9b72cd952ff1290dc190f2860497f6c68bb08dc2fa6f523bb33f59ab1","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"f45db95fde3f93731c0925b9bf8c12021921df2e4908770acdec1e3c97889277","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"regional_property_uprating.boundary","citation":"","description":"Run structural UK stage high_value_home_support.","id":"high_value_home_support","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.high_value_home_support@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_high_value_support_copy","bool"],["household","high_value_support_copies","int64"],["household","high_value_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"high_value_home_support","stage_contract_sha256":"174f4b38228d98107bee1639d1a297a2748bb618e87c7bd0a6c869c6ab06f8fa","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by high_value_home_support.","id":"high_value_home_support.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_high_value_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_high_value_support_copy","household.high_value_support_copies","household.high_value_support_copy_index"]},"population":"high_value_home_support","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_home_values.","id":"regional_home_values","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["high_value_support_copy_index","household_is_high_value_support_copy","household_source_id","region","tenure_type"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_home_values@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"main_residence_value_rank_basis","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_home_values","stage_contract_sha256":"48e8a622c8830a54a4c48d9d8cb4f011751aa05d7cb5f6c7f0e06e1121b720b1","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_components.","id":"property_components","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["main_residence_value_rank_basis","non_residential_property_value","other_residential_property_value","region","subrent"],"entity":"household","rows":"all"},{"columns":["age","is_household_head","person_is_spi_income_recipient","person_support_channel"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_components@1","mass":"conserve","outputs":[{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_rental_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_components","stage_contract_sha256":"5022c27a480f057f8b8a4f87d9305ad00b1b9c724b225e37b02403b79b99f82e","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_purchases.","id":"property_purchases","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_purchases@1","mass":"conserve","outputs":[{"column":"additional_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_purchases","stage_contract_sha256":"7af04815a11c84990306ea0293606448cdce83bb57359fe3bb4ffbf592a39fb2","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"e9496b5f8ed8e3b1e53f8d0ed8b05e2f681ab8bd107153fe6cfc18bda77d7684","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","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":"liquid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"solid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"uses_energy_prepayment_meter","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"wine_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"spirits_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_fermented_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigarettes_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"hand_rolling_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigars_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_gaming_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"pool_betting_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bingo_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"national_lottery_ticket_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_casino_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_lower_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_standard_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_higher_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_fixed_odds_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_uk_horseracing_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_other_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"betting_exchange_commission","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"horse_and_dog_pool_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"car_fuel_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"car_co2_emissions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"car_engine_size","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"car_first_registration_date","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"car_is_ved_exempt","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"383cdee98de70319226167ecce47ce037c165ab650a307420017410f6f9395d4","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"216b28835eba7a952243134dffbb45a1b3a0cdff2e3e7d0e94e2acbf754052b5","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"f072ed46fa47e369135fec63bb272fb3c928cec9eec094abcd1780187f561111","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"base":"high_value_home_support","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"1b8f99bd8bc50e3e5dacbb63b75e6b8da0c42c1c8c508c492d078e08ddab0e66","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before spi_benefit_coherence rewrites.","id":"spi_benefit_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_benefit_coherence.","id":"spi_benefit_coherence","inputs":[{"columns":["benunit_support_channel","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["aa_category","age","attendance_allowance_reported","dla_m_category","dla_m_reported","dla_sc_category","dla_sc_reported","employment_income","hours_worked","incapacity_benefit_reported","is_uc_claimant","person_source_id","person_support_channel","pip_dl_category","pip_dl_reported","pip_m_category","pip_m_reported","private_pension_income","self_employment_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_benefit_coherence@1","mass":"conserve","outputs":[{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_benefit_coherence","stage_contract_sha256":"2c0162b22d5fcab2296f654177c9f87710184c20fb323cff25710ee0667fcdef","time_period":"2024"},"population":"spi_benefit_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_benefit_coherence.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["non_residential_property_secured_debt","non_residential_property_value","other_residential_property_secured_debt","other_residential_property_value","owned_land","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","individual_savings_account_interest_income","is_benunit_head","is_household_head","is_parent","other_investment_income","person_support_channel","savings_interest_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"pension_credit_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"67478de55540a138448d9da387a64e5e2afbb17caf17b244bc3baaa34de56022","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before uc_take_up rewrites.","id":"uc_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_take_up.","id":"uc_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","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","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_take_up","stage_contract_sha256":"1f5bb5a59426d5a1f0a8ba40180b744725be29dea741a4e93924f4f55e9a7e11","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_legacy_closure_take_up.","id":"uc_legacy_closure_take_up","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","child_tax_credit_reported","esa_income_reported","housing_benefit_reported","income_support_reported","is_claimant_or_partner","jsa_income_reported","universal_credit_reported","working_tax_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_legacy_closure_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc_at_legacy_closure","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_legacy_closure_take_up","stage_contract_sha256":"bd7d87d11fb5271cd5a3e26a0268f2eaacb155fa87a9f4a8f00a6418b6da6b5c","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_take_up.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"has_mixed_age_couple_pension_credit_saving","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"e887dbbb186cb79f6d3fc9a629269dbac4a43381b9574df65353b816f01a3a35","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"c99071c19d0184440163f7ab49ee33cc19ad0ad4e2f6462ed50c36917b0da364","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["child_benefit_opts_out","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"child_benefit_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"88a0f5974de73dc778a782c9ce6e5f811e9d17e9eb86a30207bc9276134e53af","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"29198953c5522c9b996b981478909916870977a79e9f2feb2db7e9e72ef15de8","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","individual_savings_account_interest_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"b5d27d6b6307acec73a9336a00ef3e4cd900164787362e1157a49ffaa8af50ef","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","individual_savings_account_interest_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"ed54c55428e56d7597c57c8459b014aa43b2ff9495b903f0b789bd5e4264ca9a","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"f2eee57320b8bb1464c0ae4242ad614f2365f79f3b091ebc87e606e5a56f3206","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","reports_rent_from_other_property","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"c2393551258e94f0b7e9f58d4e8b5760a7f5f263737450a47897fed62e6db6dd","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_bonus_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"c9e1b8637ce83e65f3a33b410082a420c7329199c209c5c40d3acf0cf4631634","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"base":"cgt_residential_split","citation":"","description":"Ownership boundary before carers_allowance_take_up rewrites.","id":"carers_allowance_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage carers_allowance_take_up.","id":"carers_allowance_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.stage.carers_allowance_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"carers_allowance_take_up","stage_contract_sha256":"7cf2cf79bd0f9a92f2a334081a35c8bfe24a0b841131fb9a8b8aceee6caf2dba","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"carers_allowance_take_up.boundary","citation":"","description":"Ownership boundary before student_loans rewrites.","id":"student_loans.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","age_left_full_time_education","current_education","highest_education","reports_outstanding_student_loan","student_loan_repayments","student_loans","would_claim_carers_allowance"],"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"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"507ca0160144d8f5ea1b2483b812658ee8b49854e2388d50a8c59ca58f2ca9ee","time_period":"2024"},"population":"student_loans.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"student_loans.boundary","citation":"","description":"Ownership boundary before childcare_copy_take_up rewrites.","id":"childcare_copy_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage childcare_copy_take_up.","id":"childcare_copy_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_uc_childcare","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","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","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.childcare_copy_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"childcare_copy_take_up","stage_contract_sha256":"cdbb7e135b16fac7ca1bcd6c54222821e2976b4da99f10a60913efd0ba03c13c","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage private_school_attendance.","id":"private_school_attendance","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.private_school_attendance@1","mass":"conserve","outputs":[{"column":"attends_private_school","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"private_school_attendance","stage_contract_sha256":"7e44379c0331fe4c9de05cd76a075c1a6aa22cf0dec6cd2f91b277e70f14a038","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage isa_subscriptions.","id":"isa_subscriptions","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cash_isa","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","attends_private_school","dividend_income","employment_income","gender","has_lifetime_isa","individual_savings_account_interest_income","lifetime_isa_balance","loss_relief","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.isa_subscriptions@1","mass":"conserve","outputs":[{"column":"cash_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"cash_isa_subscriptions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa_subscriptions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_payments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"isa_subscriptions","stage_contract_sha256":"9fc3e3ecf333df38206c9627470ca0c1a9d8abbea7534f6367e01868fdc3081f","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage trading_allowance_receipts.","id":"trading_allowance_receipts","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","lifetime_isa_payments","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.trading_allowance_receipts@1","mass":"conserve","outputs":[{"column":"self_employment_gross_receipts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"trading_allowance_receipts","stage_contract_sha256":"f91329806570bd874750845816de96b28160e766e8e26bf1174cb0809ad8ff43","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null}],"sources":[{"codec":"csv-tables","description":"Content-bound UK FRS and donor fixture/source bundle.","name":"frs"}]} +{"country":"uk","nodes":[{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Load the source-bound UK FRS root population.","id":"create_uk_frs","inputs":[],"kernel":"uk.create@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"gender","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"months_since_last_birthday","dtype":"float64","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":"frs_care_hours_in_household","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_blind","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_uc_claimant","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"annuity_and_trust_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"individual_savings_account_interest_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":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"spousal_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":"statutory_paternity_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":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_price_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_fuel_code","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_private_fuel","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"frs_company_car_contribution","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":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"widowed_parents_allowance_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":"liable_for_share_of_household_rent","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"},{"column":"region","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"council_tax_single_adult_raw","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"external_child_payments","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"sample_fraction":1.0,"sample_seed":578,"stage_contract_sha256":"879fdd6e1e5832b94af4259b1028f852470bbe2c3ab19b61ce5f92a2e9c12ec4","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","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_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":"months_since_last_birthday","dtype":"float64","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":"frs_care_hours_in_household","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_blind","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":"is_claimant_or_partner","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_hbai_dependent_child","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_boarder","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent_paid_as_lodger","dtype":"float64","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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","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":"annuity_and_trust_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"individual_savings_account_interest_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":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maintenance_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"spousal_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":"statutory_paternity_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":"frs_bonus_amount","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_price_band","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_fuel_code","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_private_fuel","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"frs_company_car_contribution","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":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"liable_for_share_of_household_rent","dtype":"bool","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","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage age_tail.","id":"age_tail","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["external_child_payments","region"],"entity":"household","rows":"all"},{"columns":["gender"],"entity":"person","rows":"all"}],"kernel":"uk.stage.age_tail@1","mass":"conserve","outputs":[{"column":"age","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"age_tail","stage_contract_sha256":"963a34f38caede2525e3b8735f904bb70a1bbef5a272f0eefd4346343444484f","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_relationships.","id":"frs_relationships","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_household_head"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_relationships@1","mass":"conserve","outputs":[{"column":"relationship_to_head","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_role","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_family_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_looked_after_by_local_authority","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"child_limit_non_parental_caring_exception","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"ons_household_type","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_relationships","stage_contract_sha256":"ae32bf855753d3b7505e54a18532b1b53a04b6beda764cc09ad09462cf130085","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_employment.","id":"frs_employment","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_employment@1","mass":"conserve","outputs":[{"column":"employment_status","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"soc2020_major_group","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_employment","stage_contract_sha256":"c4dc3da7179c7b7d6eb67c6f119df1f213e50ee6b83a53660d317126a5773027","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_council_tax.","id":"frs_council_tax","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","soc2020_major_group"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_council_tax@1","mass":"conserve","outputs":[{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_council_tax","stage_contract_sha256":"06804f54c12d25f2afcb31eec27789802f663cb42689a932dc32f3ba5fc05fff","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_disability.","id":"frs_disability","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax","region"],"entity":"household","rows":"all"},{"columns":["afcs_reported","age","attendance_allowance_reported","dla_m_reported","dla_sc_reported","esa_contrib_reported","esa_income_reported","iidb_reported","incapacity_benefit_reported","pip_dl_reported","pip_m_reported","sda_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_disability@1","mass":"conserve","outputs":[{"column":"aa_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_sc_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"dla_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_m_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"pip_dl_category","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_disability","stage_contract_sha256":"ac500b4cb1bc04d4fb72d198592dd376d61da8c150921a6ac53914ac18be0508","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education.","id":"frs_education","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","esa_contrib_reported","esa_income_reported","is_severely_disabled_for_benefits","jsa_contrib_reported","jsa_income_reported","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education@1","mass":"conserve","outputs":[{"column":"current_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"highest_education","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_non_advanced_education","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"is_in_approved_training","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_started_or_accepted_current_education_or_training","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"is_before_universal_credit_qualifying_young_person_terminal_date","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"adult_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"child_ema","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"reports_outstanding_student_loan","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"age_left_full_time_education","dtype":"int64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education","stage_contract_sha256":"592ddc77703f19bb3e1d48b6aecffc98b4e2abd3379db84a06e011bde4fa5549","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_legacy_proxies.","id":"frs_legacy_proxies","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_legacy_proxies@1","mass":"conserve","outputs":[{"column":"legacy_jobseeker_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_health_condition_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"esa_support_group_proxy","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_legacy_proxies","stage_contract_sha256":"1ecf761cf3fa7180da15659e138e67a8654e58272b4fde28344aa27a874ad0aa","time_period":"2024"},"population":"age_tail.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"age_tail.boundary","citation":"","description":"Ownership boundary before frs_education_grant_split rewrites.","id":"frs_education_grant_split.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_education_grant_split.","id":"frs_education_grant_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent"],"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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_education_grant_split@1","mass":"conserve","outputs":[{"column":"disabled_students_allowance_eligible_expenses","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"education_grants","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_education_grant_split","stage_contract_sha256":"8718f014b90498c2cc7c754289775ca4a41452d9b978d8cbc5f34b64cbdc7df2","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_take_up.","id":"frs_take_up","inputs":[{"columns":["frs_benunit_capital","is_married"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","child_benefit_reported","education_grants","is_uc_claimant","months_since_last_birthday","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"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_take_up","stage_contract_sha256":"78aec80408c50455b37308e5a977fb70df3ecf915d6c1e8f80715ad9b58e62cf","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_person_draws.","id":"frs_person_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employment_income","employment_status","max_free_entitlement_hours_used"],"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"},{"column":"is_apprentice","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_person_draws","stage_contract_sha256":"112c502d702c640dedbc2dca7d1cfe5ae43e0f0e3ba6acfe49c738dbbfb7e693","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_household_draws.","id":"frs_household_draws","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_household_draws@1","mass":"conserve","outputs":[{"column":"household_owns_tv","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"would_evade_tv_licence_fee","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"main_residential_property_purchased_is_first_home","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"property_purchased","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_household_draws","stage_contract_sha256":"c74c63b09264319c4bf0049dabba00ecd0ce660beb7b53d6dae71518434bc949","time_period":"2024"},"population":"frs_education_grant_split.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_brma.","id":"frs_brma","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_brma@1","mass":"conserve","outputs":[{"column":"brma","dtype":"string","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_brma","stage_contract_sha256":"4285376b37299d375ed583b7f6b1747bd8b7cb1c8c0d19a36481156b5314a854","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","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_hmrc_spine_leaves.","id":"frs_hmrc_spine_leaves","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["brma","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_hmrc_spine_leaves@1","mass":"conserve","outputs":[{"column":"hmrc_spi_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_unemployment_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"hmrc_spi_incapacity_benefit_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"ossben_identifiable_subset","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"srp_regular_code5","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employer_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_hmrc_spine_leaves","stage_contract_sha256":"6b2e0264fbac47dae5e1fc4fa9e980c5c2caf7f12f165129649a559f3ad7a154","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage frs_annual_income_spells.","id":"frs_annual_income_spells","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","employer_pension_contributions","employment_income","gender","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.frs_annual_income_spells@1","mass":"conserve","outputs":[{"column":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"frs_annual_income_spells","stage_contract_sha256":"1dbdd0c9a6602be53b5527435d093a934218936d550da8b720973fc745c997ca","time_period":"2024"},"population":"frs_brma.checkpoint","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"frs_brma.checkpoint","citation":"","description":"Run structural UK stage spi_support_channel.","id":"spi_support_channel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_support_channel@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","source_household_id","int64"],["household","source_year","int64"],["household","source_household_key","string"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_support_channel","stage_contract_sha256":"2c682605139c0a8f96e8ba45a2c03f506d3f758ef437841066a8fdb8b74269b6","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_support_channel.","id":"spi_support_channel.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"source_household_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_year","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"source_household_key","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["person.person_source_id","person.person_support_channel","person.person_support_clone_index","benunit.benunit_source_id","benunit.benunit_support_channel","benunit.benunit_support_clone_index","household.source_household_id","household.source_year","household.source_household_key","household.household_source_id","household.household_support_channel","household.household_support_clone_index","household.household_is_spi_synthetic"]},"population":"spi_support_channel","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"spi_support_channel","citation":"","description":"Run structural UK stage spi_income_band_donors.","id":"spi_income_band_donors","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.spi_income_band_donors@1","mass":"declared","outputs":[],"params":{"expand_cells":[["person","person_source_id","int64"],["person","person_support_channel","string"],["person","person_support_clone_index","int64"],["benunit","benunit_source_id","int64"],["benunit","benunit_support_channel","string"],["benunit","benunit_support_clone_index","int64"],["household","household_source_id","int64"],["household","household_support_channel","string"],["household","household_support_clone_index","int64"],["household","household_is_spi_synthetic","bool"],["household","household_is_spi_income_band_donor","bool"],["household","spi_income_band_donor_lower_bound","float64"],["person","person_is_spi_income_band_carrier","bool"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_income_band_donors","stage_contract_sha256":"4754ace499836c44b00c1c53a9ef5fd686d3a29108d0d546d7a11dcc37ee8807","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by spi_income_band_donors.","id":"spi_income_band_donors.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"person_source_id","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_channel","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_support_clone_index","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_source_id","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_channel","dtype":"string","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"benunit_support_clone_index","dtype":"int64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_source_id","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_channel","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_support_clone_index","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_synthetic","dtype":"bool","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"household_is_spi_income_band_donor","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"spi_income_band_donor_lower_bound","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"person_is_spi_income_band_carrier","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_spi_income_band_donor","household.spi_income_band_donor_lower_bound","person.person_is_spi_income_band_carrier"]},"population":"spi_income_band_donors","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_spi_income_spine.","id":"hmrc_spi_income_spine","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","rent_paid_as_boarder","rent_paid_as_lodger","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","ssmg_reported","incapacity_benefit_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","ossben_identifiable_subset","srp_regular_code5","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_spi_income_spine@1","mass":"conserve","outputs":[{"column":"charitable_investment_gifts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"gift_aid","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_investment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"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":"property_finance_costs","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":"individual_savings_account_interest_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":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"trading_loss","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"loss_relief","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ni_class_4_losses_brought_forward","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_income_share","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":"employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"self_employment_income_other_spells","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"private_pension_income_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"contributory_benefits_annual_share","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"annuity_and_trust_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"},{"column":"uc_is_in_startup_period","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_includes_support_component","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"reports_rent_from_other_property","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"stands_as_sole_owner_or_partner_of_company","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_engaged_in_owned_company_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_is_main_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_trade","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_company_carries_on_property_business","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"person_is_spi_income_recipient","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_spi_income_spine","stage_contract_sha256":"481cec216d5edea741ff81c3cf939b521c0b89286ca6a67795862c6358118039","time_period":"2024"},"population":"spi_income_band_donors","sources":["frs"],"structural":"none","weights":null},{"base":"spi_income_band_donors","citation":"","description":"Ownership boundary before company_cars rewrites.","id":"company_cars.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage company_cars.","id":"company_cars","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient"],"entity":"person","rows":"all"}],"kernel":"uk.stage.company_cars@1","mass":"conserve","outputs":[{"column":"company_car_list_price","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_co2_emissions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_fuel_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_electric_range","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_capital_contributions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"company_car_private_fuel_provided","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"uc_is_in_gainful_self_employment","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"company_cars","stage_contract_sha256":"a4e0348ecb76f8550486df0682d4f2d6b7d2dee3038f5bbcf6bd0a347b7dfa6a","time_period":"2024"},"population":"company_cars.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"company_cars.boundary","citation":"","description":"Ownership boundary before spi_employment_shell rewrites.","id":"spi_employment_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_employment_shell.","id":"spi_employment_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","employment_status","gender","hmrc_spi_pay","person_is_spi_income_recipient","private_pension_income","savings_interest_income","self_employment_income","uc_is_in_gainful_self_employment"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_employment_shell@1","mass":"conserve","outputs":[{"column":"soc2020_major_group","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sic_industry_division","dtype":"int64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_sector","dtype":"string","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_employment_shell","stage_contract_sha256":"4612c78bf72a36c34a6be652d15d1348fe3d99c873fa8d5821978816b59d1618","time_period":"2024"},"population":"spi_employment_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage aps_occupation.","id":"aps_occupation","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age","employment_income","employment_sector","employment_status","gender","hmrc_spi_pay","person_is_spi_income_recipient","person_source_id","sic_industry_division","soc2020_major_group"],"entity":"person","rows":"all"}],"kernel":"uk.stage.aps_occupation@1","mass":"conserve","outputs":[{"column":"soc2020_sub_major_group","dtype":"string","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"aps_occupation","stage_contract_sha256":"644102f010870dccd28f8b980cbc5f648b7ff8ed140a0a5d9f23f02ada7f3d6d","time_period":"2024"},"population":"spi_employment_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_employment_shell.boundary","citation":"","description":"Ownership boundary before spi_housing_shell rewrites.","id":"spi_housing_shell.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_housing_shell.","id":"spi_housing_shell","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["council_tax_single_adult_raw","household_support_channel","ons_household_type","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","individual_savings_account_interest_income","is_household_head","other_investment_income","private_pension_income","property_income","savings_interest_income","self_employment_income","soc2020_sub_major_group","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_housing_shell@1","mass":"conserve","outputs":[{"column":"tenure_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"accommodation_type","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_band","dtype":"string","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"num_bedrooms","dtype":"int64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_reported","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"rent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_interest_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"mortgage_capital_repayment","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"structural_insurance_payments","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_service_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"water_and_sewerage_charges","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"domestic_rates","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"subrent","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_rebate","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"housing_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"council_tax_benefit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_housing_shell","stage_contract_sha256":"9a76a02ceddb2cd85819f57cd33feb44d645800ce963d0b18bad0f6de808fd81","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_wealth.","id":"was_wealth","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group"],"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"},{"column":"directly_held_shares","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"unit_and_investment_trusts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_secured_debt","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_wealth","stage_contract_sha256":"4c0bcaabf3695a75ec7e69d99b6b8c90570fd345067d77f1ea315f5508a88962","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage was_lisa.","id":"was_lisa","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.was_lisa@1","mass":"conserve","outputs":[{"column":"has_lifetime_isa","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_lifetime_isa_balance","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"was_lisa","stage_contract_sha256":"bf0389b9b72cd952ff1290dc190f2860497f6c68bb08dc2fa6f523bb33f59ab1","time_period":"2024"},"population":"spi_housing_shell.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_housing_shell.boundary","citation":"","description":"Ownership boundary before regional_property_uprating rewrites.","id":"regional_property_uprating.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_property_uprating.","id":"regional_property_uprating","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_lifetime_isa_balance","household_support_channel","region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_property_uprating@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"owned_land","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"other_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"non_residential_property_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_property_uprating","stage_contract_sha256":"f45db95fde3f93731c0925b9bf8c12021921df2e4908770acdec1e3c97889277","time_period":"2024"},"population":"regional_property_uprating.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"regional_property_uprating.boundary","citation":"","description":"Run structural UK stage high_value_home_support.","id":"high_value_home_support","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.high_value_home_support@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_high_value_support_copy","bool"],["household","high_value_support_copies","int64"],["household","high_value_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"high_value_home_support","stage_contract_sha256":"174f4b38228d98107bee1639d1a297a2748bb618e87c7bd0a6c869c6ab06f8fa","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by high_value_home_support.","id":"high_value_home_support.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_high_value_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"high_value_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_high_value_support_copy","household.high_value_support_copies","household.high_value_support_copy_index"]},"population":"high_value_home_support","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage regional_home_values.","id":"regional_home_values","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["high_value_support_copy_index","household_is_high_value_support_copy","household_source_id","region","tenure_type"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.regional_home_values@1","mass":"conserve","outputs":[{"column":"main_residence_value","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_wealth","dtype":"float64","entity":"household","ownership":"produced","rewrite":true,"rows":"all"},{"column":"main_residence_value_rank_basis","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"regional_home_values","stage_contract_sha256":"48e8a622c8830a54a4c48d9d8cb4f011751aa05d7cb5f6c7f0e06e1121b720b1","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_components.","id":"property_components","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["main_residence_value_rank_basis","non_residential_property_value","other_residential_property_value","region","subrent"],"entity":"household","rows":"all"},{"columns":["age","is_household_head","person_is_spi_income_recipient","person_support_channel"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_components@1","mass":"conserve","outputs":[{"column":"property_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_finance_costs","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"property_rental_income","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_components","stage_contract_sha256":"5022c27a480f057f8b8a4f87d9305ad00b1b9c724b225e37b02403b79b99f82e","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage property_purchases.","id":"property_purchases","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.property_purchases@1","mass":"conserve","outputs":[{"column":"additional_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"non_residential_property_purchased","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"property_purchases","stage_contract_sha256":"7af04815a11c84990306ea0293606448cdce83bb57359fe3bb4ffbf592a39fb2","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage nts_bus_travel.","id":"nts_bus_travel","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.nts_bus_travel@1","mass":"conserve","outputs":[{"column":"local_bus_use_band","dtype":"int64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_in_london_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"other_local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_trips","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"bus_pass_eligible","dtype":"bool","entity":"person","ownership":"produced","rows":"all"},{"column":"local_bus_single_fare_share","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"household_local_bus_trips","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"nts_bus_travel","stage_contract_sha256":"e9496b5f8ed8e3b1e53f8d0ed8b05e2f681ab8bd107153fe6cfc18bda77d7684","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage lcfs_consumption.","id":"lcfs_consumption","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","household_local_bus_trips"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","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":"liquid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"solid_fuel_consumption","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"has_fuel_consumption","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"uses_energy_prepayment_meter","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"wine_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"spirits_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_fermented_litres","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"beer_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cider_draught_share","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigarettes_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"hand_rolling_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"cigars_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"other_tobacco_grams_per_week","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_gaming_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"pool_betting_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bingo_net_receipts","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"national_lottery_ticket_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_casino_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_lower_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_standard_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"machine_games_higher_rate_net_takings","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"land_based_fixed_odds_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_uk_horseracing_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"remote_other_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"betting_exchange_commission","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"horse_and_dog_pool_betting_net_losses","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"car_fuel_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"car_co2_emissions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"car_engine_size","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"car_first_registration_date","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"car_is_ved_exempt","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"lcfs_consumption","stage_contract_sha256":"383cdee98de70319226167ecce47ce037c165ab650a307420017410f6f9395d4","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_vat.","id":"etb_vat","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_vat@1","mass":"conserve","outputs":[{"column":"full_rate_vat_expenditure_rate","dtype":"float64","entity":"household","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_vat","stage_contract_sha256":"216b28835eba7a952243134dffbb45a1b3a0cdff2e3e7d0e94e2acbf754052b5","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage etb_services.","id":"etb_services","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt"],"entity":"person","rows":"all"}],"kernel":"uk.stage.etb_services@1","mass":"conserve","outputs":[{"column":"dfe_education_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"bus_subsidy_spending","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"rail_usage","dtype":"float64","entity":"household","ownership":"produced","rows":"all"},{"column":"a_and_e_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"admitted_patient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"outpatient_visits","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_a_and_e_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_admitted_patient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"nhs_outpatient_spending","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"etb_services","stage_contract_sha256":"f072ed46fa47e369135fec63bb272fb3c928cec9eec094abcd1780187f561111","time_period":"2024"},"population":"high_value_home_support","sources":["frs"],"structural":"none","weights":null},{"base":"high_value_home_support","citation":"","description":"Ownership boundary before uc_reporter_redraw rewrites.","id":"uc_reporter_redraw.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_reporter_redraw.","id":"uc_reporter_redraw","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_reporter_redraw@1","mass":"conserve","outputs":[{"column":"universal_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_reporter_redraw","stage_contract_sha256":"1b8f99bd8bc50e3e5dacbb63b75e6b8da0c42c1c8c508c492d078e08ddab0e66","time_period":"2024"},"population":"uc_reporter_redraw.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_reporter_redraw.boundary","citation":"","description":"Ownership boundary before spi_benefit_coherence rewrites.","id":"spi_benefit_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage spi_benefit_coherence.","id":"spi_benefit_coherence","inputs":[{"columns":["benunit_support_channel","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["aa_category","age","attendance_allowance_reported","dla_m_category","dla_m_reported","dla_sc_category","dla_sc_reported","employment_income","hours_worked","incapacity_benefit_reported","is_uc_claimant","person_source_id","person_support_channel","pip_dl_category","pip_dl_reported","pip_m_category","pip_m_reported","private_pension_income","self_employment_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.spi_benefit_coherence@1","mass":"conserve","outputs":[{"column":"jsa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"esa_income_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"income_support_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"working_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_tax_credit_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"sda_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"ssmg_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"iidb_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"afcs_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"bsp_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"war_widows_pension_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"widowed_parents_allowance_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":"esa_contrib_reported","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_enhanced_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"is_severely_disabled_for_benefits","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"receives_benefits_in_own_right","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"spi_benefit_coherence","stage_contract_sha256":"2c0162b22d5fcab2296f654177c9f87710184c20fb323cff25710ee0667fcdef","time_period":"2024"},"population":"spi_benefit_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"spi_benefit_coherence.boundary","citation":"","description":"Ownership boundary before uc_capital_coherence rewrites.","id":"uc_capital_coherence.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_capital_coherence.","id":"uc_capital_coherence","inputs":[{"columns":["benunit_support_channel","dependent_children","is_married"],"entity":"benunit","rows":"all"},{"columns":["non_residential_property_secured_debt","non_residential_property_value","other_residential_property_secured_debt","other_residential_property_value","owned_land","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","individual_savings_account_interest_income","is_benunit_head","is_household_head","is_parent","other_investment_income","person_support_channel","savings_interest_income","universal_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_capital_coherence@1","mass":"conserve","outputs":[{"column":"uc_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"pension_credit_reported_capital","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"frs_benunit_capital","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_capital_coherence","stage_contract_sha256":"67478de55540a138448d9da387a64e5e2afbb17caf17b244bc3baaa34de56022","time_period":"2024"},"population":"uc_capital_coherence.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_capital_coherence.boundary","citation":"","description":"Ownership boundary before uc_take_up rewrites.","id":"uc_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_take_up.","id":"uc_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","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","pension_credit_reported_capital"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_take_up","stage_contract_sha256":"1f5bb5a59426d5a1f0a8ba40180b744725be29dea741a4e93924f4f55e9a7e11","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_legacy_closure_take_up.","id":"uc_legacy_closure_take_up","inputs":[{"columns":["frs_benunit_capital","would_claim_uc"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","child_tax_credit_reported","esa_income_reported","housing_benefit_reported","income_support_reported","is_claimant_or_partner","jsa_income_reported","universal_credit_reported","working_tax_credit_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_legacy_closure_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_uc_at_legacy_closure","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_legacy_closure_take_up","stage_contract_sha256":"bd7d87d11fb5271cd5a3e26a0268f2eaacb155fa87a9f4a8f00a6418b6da6b5c","time_period":"2024"},"population":"uc_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"uc_take_up.boundary","citation":"","description":"Ownership boundary before pension_credit_take_up rewrites.","id":"pension_credit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage pension_credit_take_up.","id":"pension_credit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_uc","would_claim_tfc","would_claim_extended_childcare","would_claim_universal_childcare","would_claim_targeted_childcare","would_claim_uc_childcare","maximum_extended_childcare_hours_usage","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.pension_credit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_pc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"has_mixed_age_couple_pension_credit_saving","dtype":"bool","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"pension_credit_take_up","stage_contract_sha256":"e887dbbb186cb79f6d3fc9a629269dbac4a43381b9574df65353b816f01a3a35","time_period":"2024"},"population":"pension_credit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"pension_credit_take_up.boundary","citation":"","description":"Ownership boundary before child_benefit_take_up rewrites.","id":"child_benefit_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage child_benefit_take_up.","id":"child_benefit_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.child_benefit_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_child_benefit","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"child_benefit_opts_out","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"child_benefit_take_up","stage_contract_sha256":"c99071c19d0184440163f7ab49ee33cc19ad0ad4e2f6462ed50c36917b0da364","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage uc_deduction_attributes.","id":"uc_deduction_attributes","inputs":[{"columns":["child_benefit_opts_out","frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age"],"entity":"person","rows":"all"}],"kernel":"uk.stage.uc_deduction_attributes@1","mass":"conserve","outputs":[{"column":"uc_deduction_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_type_random_draw","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_latent_deduction_rate","dtype":"float64","entity":"benunit","ownership":"produced","rows":"all"},{"column":"uc_deduction_combination","dtype":"string","entity":"benunit","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"uc_deduction_attributes","stage_contract_sha256":"6bc7e3ec1a5712e23ca1b7d2956e8b17f2526b94431ba3e5a9294b04658e4fe0","time_period":"2024"},"population":"child_benefit_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"child_benefit_take_up.boundary","citation":"","description":"Run structural UK stage cgt_support_split.","id":"cgt_support_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_support_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_support_copy","bool"],["household","cgt_support_copies","int64"],["household","cgt_support_copy_index","int64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_support_split","stage_contract_sha256":"88a0f5974de73dc778a782c9ce6e5f811e9d17e9eb86a30207bc9276134e53af","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_support_split.","id":"cgt_support_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_support_copy","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copies","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_support_copy_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_support_copy","household.cgt_support_copies","household.cgt_support_copy_index"]},"population":"cgt_support_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_support_split","citation":"","description":"Run structural UK stage cgt_incidence_clone.","id":"cgt_incidence_clone","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_clone@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_capital_gains_clone","bool"],["person","capital_gains","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_clone","stage_contract_sha256":"29198953c5522c9b996b981478909916870977a79e9f2feb2db7e9e72ef15de8","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_incidence_clone.","id":"cgt_incidence_clone.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_capital_gains_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_capital_gains_clone","person.capital_gains"]},"population":"cgt_incidence_clone","sources":[],"structural":"none","weights":null},{"base":"cgt_incidence_clone","citation":"","description":"Ownership boundary before hmrc_cgt_gains_spine rewrites.","id":"hmrc_cgt_gains_spine.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_gains_spine.","id":"hmrc_cgt_gains_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cgt_support_copies","corporate_wealth","gross_financial_wealth","household_is_cgt_support_copy","non_residential_property_value","other_residential_property_value","region"],"entity":"household","rows":"all"},{"columns":["age","dividend_income","employment_income","individual_savings_account_interest_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_gains_spine@1","mass":"conserve","outputs":[{"column":"capital_gains","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_gains_spine","stage_contract_sha256":"b5d27d6b6307acec73a9336a00ef3e4cd900164787362e1157a49ffaa8af50ef","time_period":"2024"},"population":"hmrc_cgt_gains_spine.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"hmrc_cgt_gains_spine.boundary","citation":"","description":"Run structural UK stage cgt_incidence_anchor.","id":"cgt_incidence_anchor","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_is_capital_gains_clone","region"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","dividend_income","employment_income","individual_savings_account_interest_income","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_incidence_anchor@1","mass":"conserve","outputs":[],"params":{"expand_cells":[],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_incidence_anchor","stage_contract_sha256":"ed54c55428e56d7597c57c8459b014aa43b2ff9495b903f0b789bd5e4264ca9a","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":"cgt_incidence_anchor","citation":"","description":"Run structural UK stage cgt_residential_split.","id":"cgt_residential_split","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains"],"entity":"person","rows":"all"}],"kernel":"uk.stage.expand.cgt_residential_split@1","mass":"conserve","outputs":[],"params":{"expand_cells":[["household","household_is_cgt_residential_clone","bool"],["household","cgt_residential_clone_index","int64"],["person","cgt_residential_probability","float64"],["person","capital_gains_residential_property","float64"]],"expand_weight_entity":"household","expand_weight_kind":"importance","numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"cgt_residential_split","stage_contract_sha256":"f2eee57320b8bb1464c0ae4242ad614f2365f79f3b091ebc87e606e5a56f3206","time_period":"2024"},"population":null,"sources":["frs"],"structural":"expand","weights":null},{"base":null,"citation":"","description":"Own the cells materialized by cgt_residential_split.","id":"cgt_residential_split.owned","inputs":[],"kernel":"uk.claim@1","mass":"conserve","outputs":[{"column":"household_is_cgt_residential_clone","dtype":"bool","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_clone_index","dtype":"int64","entity":"household","ownership":"produced","rows":"all"},{"column":"cgt_residential_probability","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_residential_property","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"materialized_expand_outputs":["household.household_is_cgt_residential_clone","household.cgt_residential_clone_index","person.cgt_residential_probability","person.capital_gains_residential_property"]},"population":"cgt_residential_split","sources":[],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage hmrc_cgt_asset_type_spine.","id":"hmrc_cgt_asset_type_spine","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["corporate_wealth","gross_financial_wealth","other_residential_property_value","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","capital_gains","capital_gains_residential_property","dividend_income","property_income","reports_rent_from_other_property","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.hmrc_cgt_asset_type_spine@1","mass":"conserve","outputs":[{"column":"capital_gains_asset_type","dtype":"string","entity":"person","ownership":"produced","rows":"all"},{"column":"capital_gains_badr","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"hmrc_cgt_asset_type_spine","stage_contract_sha256":"c2393551258e94f0b7e9f58d4e8b5760a7f5f263737450a47897fed62e6db6dd","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage salary_sacrifice.","id":"salary_sacrifice","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr"],"entity":"person","rows":"all"}],"kernel":"uk.stage.salary_sacrifice@1","mass":"conserve","outputs":[{"column":"pension_contributions_via_salary_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"pension_contributions_via_bonus_sacrifice","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"employee_pension_contributions","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"employment_income","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"},{"column":"salary_sacrifice_pre_conversion_pay","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"salary_sacrifice","stage_contract_sha256":"c9e1b8637ce83e65f3a33b410082a420c7329199c209c5c40d3acf0cf4631634","time_period":"2024"},"population":"cgt_residential_split","sources":["frs"],"structural":"none","weights":null},{"base":"cgt_residential_split","citation":"","description":"Ownership boundary before carers_allowance_take_up rewrites.","id":"carers_allowance_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage carers_allowance_take_up.","id":"carers_allowance_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","child_benefit_reported","income_support_reported","housing_benefit_reported","attendance_allowance_reported","dla_sc_reported","dla_m_reported","iidb_reported","carers_allowance_reported","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.stage.carers_allowance_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_carers_allowance","dtype":"bool","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"carers_allowance_take_up","stage_contract_sha256":"7cf2cf79bd0f9a92f2a334081a35c8bfe24a0b841131fb9a8b8aceee6caf2dba","time_period":"2024"},"population":"carers_allowance_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"carers_allowance_take_up.boundary","citation":"","description":"Ownership boundary before student_loans rewrites.","id":"student_loans.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage student_loans.","id":"student_loans","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["region"],"entity":"household","rows":"all"},{"columns":["age","age_left_full_time_education","current_education","highest_education","reports_outstanding_student_loan","student_loan_repayments","student_loans","would_claim_carers_allowance"],"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"},{"column":"student_loan_balance","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"student_loans","stage_contract_sha256":"507ca0160144d8f5ea1b2483b812658ee8b49854e2388d50a8c59ca58f2ca9ee","time_period":"2024"},"population":"student_loans.boundary","sources":["frs"],"structural":"none","weights":null},{"base":"student_loans.boundary","citation":"","description":"Ownership boundary before childcare_copy_take_up rewrites.","id":"childcare_copy_take_up.boundary","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.identity@1","mass":"conserve","outputs":[],"params":{},"population":null,"sources":[],"structural":"filter","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage childcare_copy_take_up.","id":"childcare_copy_take_up","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","would_claim_child_benefit","child_benefit_opts_out","would_claim_pc","would_claim_uc","would_claim_uc_childcare","benunit_source_id","benunit_support_channel","benunit_support_clone_index","uc_reported_capital","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","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","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.childcare_copy_take_up@1","mass":"conserve","outputs":[{"column":"would_claim_tfc","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_extended_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_universal_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"would_claim_targeted_childcare","dtype":"bool","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"maximum_extended_childcare_hours_usage","dtype":"float64","entity":"benunit","ownership":"produced","rewrite":true,"rows":"all"},{"column":"max_free_entitlement_hours_used","dtype":"float64","entity":"person","ownership":"produced","rewrite":true,"rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"childcare_copy_take_up","stage_contract_sha256":"cdbb7e135b16fac7ca1bcd6c54222821e2976b4da99f10a60913efd0ba03c13c","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage private_school_attendance.","id":"private_school_attendance","inputs":[{"columns":["frs_benunit_capital","is_married","dependent_children","liable_for_share_of_household_rent","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","pension_credit_reported_capital","would_claim_uc_at_legacy_closure","has_mixed_age_couple_pension_credit_saving","uc_deduction_random_draw","uc_deduction_type_random_draw","uc_latent_deduction_rate","uc_deduction_combination"],"entity":"benunit","rows":"all"},{"columns":["region","tenure_type","accommodation_type","num_bedrooms","council_tax_reported","council_tax_band","council_tax_rebate","council_tax_single_adult_raw","water_and_sewerage_charges","domestic_rates","rent","subrent","mortgage_interest_repayment","mortgage_capital_repayment","structural_insurance_payments","housing_service_charges","external_child_payments","ons_household_type","council_tax","household_owns_tv","would_evade_tv_licence_fee","main_residential_property_purchased_is_first_home","property_purchased","brma","source_household_id","source_year","source_household_key","household_source_id","household_support_channel","household_support_clone_index","household_is_spi_synthetic","household_is_spi_income_band_donor","spi_income_band_donor_lower_bound","owned_land","property_wealth","corporate_wealth","private_pension_wealth","gross_financial_wealth","net_financial_wealth","main_residence_value","other_residential_property_value","non_residential_property_value","savings","num_vehicles","cash_isa","stocks_and_shares_isa","mortgage_debt","consumer_debt","directly_held_shares","unit_and_investment_trusts","other_residential_property_secured_debt","non_residential_property_secured_debt","household_lifetime_isa_balance","household_is_high_value_support_copy","high_value_support_copies","high_value_support_copy_index","main_residence_value_rank_basis","additional_residential_property_purchased","non_residential_property_purchased","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","liquid_fuel_consumption","solid_fuel_consumption","has_fuel_consumption","uses_energy_prepayment_meter","beer_litres","cider_litres","wine_litres","spirits_litres","other_fermented_litres","beer_draught_share","cider_draught_share","cigarettes_per_week","hand_rolling_tobacco_grams_per_week","cigars_grams_per_week","other_tobacco_grams_per_week","remote_gaming_net_losses","pool_betting_net_receipts","bingo_net_receipts","national_lottery_ticket_spending","land_based_casino_net_losses","machine_games_lower_rate_net_takings","machine_games_standard_rate_net_takings","machine_games_higher_rate_net_takings","land_based_fixed_odds_betting_net_losses","remote_uk_horseracing_betting_net_losses","remote_other_betting_net_losses","betting_exchange_commission","horse_and_dog_pool_betting_net_losses","full_rate_vat_expenditure_rate","dfe_education_spending","rail_subsidy_spending","bus_subsidy_spending","rail_usage","household_is_cgt_support_copy","cgt_support_copies","cgt_support_copy_index","household_is_capital_gains_clone","household_is_cgt_residential_clone","cgt_residential_clone_index"],"entity":"household","rows":"all"},{"columns":["age","gender","months_since_last_birthday","marital_status","hours_worked","care_hours","frs_care_hours_in_household","is_household_head","is_benunit_head","is_parent","is_blind","is_uc_claimant","is_claimant_or_partner","is_hbai_dependent_child","uc_is_in_startup_period","uc_is_in_gainful_self_employment","rent_paid_as_boarder","rent_paid_as_lodger","employment_income","self_employment_income","trading_loss","loss_relief","ni_class_4_losses_brought_forward","private_pension_income","annuity_and_trust_income","individual_savings_account_interest_income","savings_interest_income","dividend_income","other_investment_income","stands_as_sole_owner_or_partner_of_company","is_engaged_in_owned_company_trade","owned_company_is_main_employment","owned_company_carries_on_trade","owned_company_carries_on_property_business","owned_company_income_share","property_income","reports_rent_from_other_property","maintenance_income","spousal_maintenance_income","miscellaneous_income","private_transfer_income","lump_sum_income","student_loan_repayments","statutory_sick_pay","statutory_maternity_pay","statutory_paternity_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","frs_bonus_amount","frs_company_car_price_band","frs_company_car_fuel_code","frs_company_car_private_fuel","frs_company_car_contribution","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","esa_includes_support_component","bsp_reported","war_widows_pension_reported","widowed_parents_allowance_reported","relationship_to_head","ons_family_role","ons_family_index","is_looked_after_by_local_authority","child_limit_non_parental_caring_exception","employment_status","employment_sector","sic_industry_division","soc2020_major_group","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","reports_outstanding_student_loan","age_left_full_time_education","legacy_jobseeker_proxy","esa_health_condition_proxy","esa_support_group_proxy","disabled_students_allowance_eligible_expenses","max_free_entitlement_hours_used","would_claim_marriage_allowance","would_claim_scp","attends_private_school_random_draw","tax_free_childcare_spend_routed_share","is_apprentice","hmrc_spi_pay","hmrc_spi_unemployment_benefit_income","hmrc_spi_incapacity_benefit_income","ossben_identifiable_subset","srp_regular_code5","employer_pension_contributions","employment_income_annual_share","employment_income_other_spells","self_employment_income_annual_share","self_employment_income_other_spells","private_pension_income_annual_share","contributory_benefits_annual_share","person_source_id","person_support_channel","person_support_clone_index","person_is_spi_income_band_carrier","charitable_investment_gifts","gift_aid","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","property_finance_costs","hmrc_spi_employed_income","hmrc_spi_total_earned_income","hmrc_spi_total_investment_income","hmrc_spi_assessable_income","person_is_spi_income_recipient","company_car_list_price","company_car_co2_emissions","company_car_fuel_type","company_car_electric_range","company_car_capital_contributions","company_car_private_fuel_provided","soc2020_sub_major_group","student_loan_balance","has_lifetime_isa","lifetime_isa_balance","property_rental_income","local_bus_use_band","bus_in_london_trips","other_local_bus_trips","local_bus_trips","bus_pass_eligible","local_bus_single_fare_share","car_fuel_type","car_co2_emissions","car_engine_size","car_first_registration_date","car_is_ved_exempt","a_and_e_visits","admitted_patient_visits","outpatient_visits","nhs_a_and_e_spending","nhs_admitted_patient_spending","nhs_outpatient_spending","capital_gains","cgt_residential_probability","capital_gains_residential_property","capital_gains_asset_type","capital_gains_badr","pension_contributions_via_bonus_sacrifice","salary_sacrifice_pre_conversion_pay","student_loan_plan"],"entity":"person","rows":"all"}],"kernel":"uk.stage.private_school_attendance@1","mass":"conserve","outputs":[{"column":"attends_private_school","dtype":"bool","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"private_school_attendance","stage_contract_sha256":"7e44379c0331fe4c9de05cd76a075c1a6aa22cf0dec6cd2f91b277e70f14a038","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage isa_subscriptions.","id":"isa_subscriptions","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["cash_isa","region","stocks_and_shares_isa"],"entity":"household","rows":"all"},{"columns":["age","attends_private_school","dividend_income","employment_income","gender","has_lifetime_isa","individual_savings_account_interest_income","lifetime_isa_balance","loss_relief","miscellaneous_income","private_pension_income","property_income","savings_interest_income","self_employment_income","state_pension_reported"],"entity":"person","rows":"all"}],"kernel":"uk.stage.isa_subscriptions@1","mass":"conserve","outputs":[{"column":"cash_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa_balance","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"cash_isa_subscriptions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"stocks_and_shares_isa_subscriptions","dtype":"float64","entity":"person","ownership":"produced","rows":"all"},{"column":"lifetime_isa_payments","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"isa_subscriptions","stage_contract_sha256":"9fc3e3ecf333df38206c9627470ca0c1a9d8abbea7534f6367e01868fdc3081f","time_period":"2024"},"population":"childcare_copy_take_up.boundary","sources":["frs"],"structural":"none","weights":null},{"artifact_outputs":[{"name":"stage_evidence","type":{"name":"microcosm.stage-evidence","schema_version":1}}],"base":null,"citation":"","description":"Run UK spine stage trading_allowance_receipts.","id":"trading_allowance_receipts","inputs":[{"columns":["frs_benunit_capital"],"entity":"benunit","rows":"all"},{"columns":["household_source_id","region"],"entity":"household","rows":"all"},{"columns":["age","lifetime_isa_payments","self_employment_income"],"entity":"person","rows":"all"}],"kernel":"uk.stage.trading_allowance_receipts@1","mass":"conserve","outputs":[{"column":"self_employment_gross_receipts","dtype":"float64","entity":"person","ownership":"produced","rows":"all"}],"params":{"numerical_dependencies":[["policyengine-uk","2.174.1"],["policyengine-core","3.33.3"],["numpy","2.4.6"],["pandas","3.0.3"],["scikit-learn","1.8.0"],["quantile-forest","1.4.2"]],"stage":"trading_allowance_receipts","stage_contract_sha256":"f91329806570bd874750845816de96b28160e766e8e26bf1174cb0809ad8ff43","time_period":"2024"},"population":"childcare_copy_take_up.boundary","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/tools/graph_uk_spine_fixture.py b/tools/graph_uk_spine_fixture.py index b4edff878d..671bb93505 100644 --- a/tools/graph_uk_spine_fixture.py +++ b/tools/graph_uk_spine_fixture.py @@ -230,8 +230,10 @@ "marital_status", "employment_status", "employment_sector", - # The SOC 2020 major group of the main or last job (microcosm#1490). + # The SOC 2020 major group of the main or last job, and the sub-major + # group drawn within it (microcosm#1490). "soc2020_major_group", + "soc2020_sub_major_group", "aa_category", "dla_sc_category", "dla_m_category", @@ -2169,8 +2171,8 @@ def _normalize_legacy_strings(frame: Frame) -> Frame: for entity, columns in _NORMALIZED_STRING_COLUMNS.items() for column in columns ] - if observed != expected_order or len(observed) != 30: - raise RuntimeError("The legacy normalization audit is not exactly 30 cells.") + if observed != expected_order or len(observed) != 31: + raise RuntimeError("The legacy normalization audit is not exactly 31 cells.") return Frame( tables, frame.schema, From ccf01cf2efd4fc9bebdbd0262e676de083683df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mar=C3=ADa=20Juaristi?= <127882282+juaristi22@users.noreply.github.com> Date: Wed, 4 Nov 2026 19:07:24 +0000 Subject: [PATCH 7/7] Read the APS tab a chunk at a time, keeping only the stage's twelve columns (#1512) The head arm's spine peaked at 12.8 GiB, against 9.6 on the control, and the APS read caused it. The shared read_pinned_tab parses the whole 548-column tab in one pass to keep 12 of its columns, a 2.4 GiB transient. aps_occupation now reads through read_pinned_columns. It checks the same size and sha256 pins, then reads only the named columns as text, a chunk of rows at a time, and converts them to numbers as the shared reader does. On the pinned tab the read no longer raises peak memory, takes the same second, and returns an identical table. The licensed-only resource test reads through the new reader, and a synthetic test holds it equal to read_pinned_tab. Co-Authored-By: Claude Opus 5.5 --- .../build/uk_runtime/aps_occupation.py | 61 +++++++++++++++++-- .../engine_free/uk/test_uk_aps_occupation.py | 23 +++++++ .../uk/test_uk_occupation_resources.py | 7 ++- 3 files changed, 84 insertions(+), 7 deletions(-) diff --git a/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py index 71d713a53e..6cd54c2f8c 100644 --- a/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py +++ b/packages/microcosm-build/src/microcosm/build/uk_runtime/aps_occupation.py @@ -39,6 +39,7 @@ integer_record_keys, stable_identity_uniforms, ) +from microcosm.build.trace import sha256_file from microcosm.build.uk_runtime.occupation_constants import ( UK_OCCUPATION_STATUS_GROUP, UK_SIC2007_SECTION_DIVISIONS, @@ -77,6 +78,7 @@ "UKAPSOccupationStageTransform", "clean_aps_occupation_table", "impute_soc2020_sub_major_group", + "read_pinned_columns", "sub_major_model", ] @@ -744,6 +746,59 @@ def _assert_invariants(person_in: pd.DataFrame, person_out: pd.DataFrame) -> Non ) +def read_pinned_columns( + path: Path, + artifact: Mapping[str, Any], + columns: Sequence[str], + *, + chunk_rows: int = 20_000, +) -> pd.DataFrame: + """The named columns of a size- and sha256-pinned tab, read a chunk at a time. + + The shared ``read_pinned_tab`` parses a whole tab in one pass, which for + the APS person tab (548 columns) costs some 2.4 GiB of memory to keep 12 + of them. This checks the same pins, then reads only the named columns + (matched case-insensitively) as text, a chunk of rows at a time, and + converts them to numbers as that reader does, under lower-case names. + """ + if not path.exists(): + raise FileNotFoundError(f"The pinned tab is missing: {path}.") + size = path.stat().st_size + if size != int(artifact["size_bytes"]): + raise ValueError( + f"The tab {path.name} is {size} bytes, not the pinned " + f"{int(artifact['size_bytes'])}." + ) + digest = sha256_file(path) + if digest != str(artifact["sha256"]): + raise ValueError( + f"The tab {path.name} hashes to {digest}, not the pinned " + f"{artifact['sha256']}." + ) + names: dict[str, list[str]] = {} + for name in pd.read_csv(path, sep="\t", nrows=0).columns: + names.setdefault(str(name).lower(), []).append(str(name)) + wanted = [str(column).lower() for column in columns] + missing = sorted(column for column in wanted if column not in names) + if missing: + raise ValueError(f"{path.name} is missing required column(s): {missing}.") + repeated = sorted(column for column in wanted if len(names[column]) > 1) + if repeated: + raise ValueError( + f"{path.name} has duplicate column(s) after lower-casing: {repeated}." + ) + chunks = pd.read_csv( + path, + sep="\t", + usecols=[names[column][0] for column in wanted], + dtype=str, + chunksize=chunk_rows, + ) + raw = pd.concat(list(chunks), ignore_index=True) + raw.columns = [str(column).lower() for column in raw.columns] + return raw.apply(pd.to_numeric, errors="coerce") + + def _artifact(stage, role: str) -> Mapping[str, Any]: for artifact in stage.artifacts: if artifact.get("role") == role: @@ -778,12 +833,10 @@ def _raw_donor(self) -> pd.DataFrame: f"{UK_APS_OCCUPATION_STAGE_NAME} requires the caller-supplied APS " "person tab." ) - from microcosm.build.uk_runtime.frs_spine import read_pinned_tab - - return read_pinned_tab( + return read_pinned_columns( Path(self.aps_tab_path).expanduser().resolve(), _artifact(self.stage, UK_APS_PERSON_TAB_ROLE), - columns=list(UK_APS_OCCUPATION_CLEANING["columns"].values()), + list(UK_APS_OCCUPATION_CLEANING["columns"].values()), ) def __call__(self, frame): diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py index 66ec7f34c4..811c4568ca 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_aps_occupation.py @@ -121,6 +121,29 @@ def test_a_digest_mismatch_is_refused(tmp_path) -> None: transform._raw_donor() +def test_the_chunked_reader_matches_the_shared_pinned_reader(tmp_path, raw) -> None: + import hashlib + + from microcosm.build.uk_runtime.aps_occupation import read_pinned_columns + from microcosm.build.uk_runtime.frs_spine import read_pinned_tab + + tab = tmp_path / "aps.tab" + raw.to_csv(tab, sep="\t", index=False) + artifact = { + "size_bytes": tab.stat().st_size, + "sha256": hashlib.sha256(tab.read_bytes()).hexdigest(), + } + columns = list(UK_APS_OCCUPATION_CLEANING["columns"].values()) + chunked = read_pinned_columns(tab, artifact, columns, chunk_rows=500) + pd.testing.assert_frame_equal( + chunked, read_pinned_tab(tab, artifact, columns=columns) + ) + with pytest.raises(ValueError, match="not the pinned"): + read_pinned_columns(tab, {**artifact, "size_bytes": 1}, columns) + with pytest.raises(ValueError, match="missing required column"): + read_pinned_columns(tab, artifact, [*columns, "NOT_A_COLUMN"]) + + def test_a_missing_tab_is_refused() -> None: with pytest.raises(ValueError, match="requires the caller-supplied APS"): UKAPSOccupationStageTransform(stage=_stage())._raw_donor() diff --git a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py index 298369740c..6f4d4994a0 100644 --- a/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py +++ b/packages/microcosm-build/tests/engine_free/uk/test_uk_occupation_resources.py @@ -18,8 +18,9 @@ UK_APS_PERSON_TAB_ROLE, _artifact, clean_aps_occupation_table, + read_pinned_columns, ) -from microcosm.build.uk_runtime.frs_spine import REGION_MAP, read_pinned_tab +from microcosm.build.uk_runtime.frs_spine import REGION_MAP from microcosm.build.uk_runtime.occupation_constants import ( UK_SOC2020_SUB_MAJOR_GROUPS, ) @@ -32,10 +33,10 @@ def test_the_aps_cleaning_maps_every_code_of_the_licensed_tab() -> None: stage = next( s for s in load_country_spec("uk").sources.stages if s.stage == "aps_occupation" ) - raw = read_pinned_tab( + raw = read_pinned_columns( Path(tab), _artifact(stage, UK_APS_PERSON_TAB_ROLE), - columns=list(UK_APS_OCCUPATION_CLEANING["columns"].values()), + list(UK_APS_OCCUPATION_CLEANING["columns"].values()), ) donors, receipt = clean_aps_occupation_table(raw) assert set(donors["soc2020_sub_major_group"]) == set(