Skip to content

processing.formatting

Formatting module.

processing.formatting.usable_records

Select the records a formatter may see, by reading a verdict rather than making one.

A formatter does not decide which records exist. cascade_completeness decides that once, for every consumer, and stamps it as a usability profile; this reads the profile the config names and keeps what it admits.

That is the whole of it, and the reason is arithmetic rather than tidiness. The weighting sums over the records a profile admits, so anything the formatter removed afterwards would leave a weight standing for records that are not in the output. Filtering on the same verdict the weighting used, and checking that the records kept carry every weight that came in, makes the two agree.

Which records survive is decided by keep_records, which lives beside the cascade so the weighting can read the same answer.

Weights and joint ids are read for the profile this consumer names, so its universe, its weights and its joint tours are the same universe. Where a record still carries no weight it is reported, not removed: a zero means its scope kept no usable record to share the parent's claim among, a null means no weight was ever estimated for it, and both are recoverable in a way that deleting the record is not.

keep_usable

keep_usable(
    tables: dict[str, pl.DataFrame], usability_profile: str
) -> dict[str, pl.DataFrame]

Keep the records usability_profile admits, across every table.

Parameters:

Name Type Description Default
tables dict[str, pl.DataFrame]

Canonical tables, keyed by name.

required
usability_profile str

The usability profile this consumer reads. It names both the verdict to gate on (usable_<profile>) and the weights to read (hh_weight_<profile>), so one setting settles both.

required

Returns:

Type Description
dict[str, pl.DataFrame]

The same mapping, filtered, with this profile's weights under the base

dict[str, pl.DataFrame]

column names. Tables absent from the input stay absent.

Raises:

Type Description
ValueError

If a gated table carries no verdict, which means cascade_completeness did not run or stamped a different profile.

processing.formatting.usual_workplace

A model's usual workplace: the reported one, else the one found from trips.

Activity-based models send every work tour to the person's usual workplace, and a worker without one makes no work tours. The survey only asks for a workplace when the job has one fixed location, so a worker whose location varies, or who works remotely, has none -- even when their trips show them working at the same place day after day.

Here that observed workplace stands in. It is an inference, made only for the model formatters and only where the survey gave nothing: canonical persons keep the reported workplace alone, a reported workplace is never replaced, and only someone employed gets one.

fill_usual_workplace

fill_usual_workplace(
    persons: pl.DataFrame,
    habitual_locations: pl.DataFrame | None,
    habitual_location_days: pl.DataFrame | None,
    *,
    zone_names: list[str]
) -> pl.DataFrame

Give employed persons with no reported workplace their observed one.

Parameters:

Name Type Description Default
persons pl.DataFrame

Persons with employment, work_lat, work_lon and work_<zone>.

required
habitual_locations pl.DataFrame | None

Habitual locations with lat, lon and a column per zone in zone_names (see add_zone_ids). None leaves persons as they are.

required
habitual_location_days pl.DataFrame | None

Time spent at each location per day.

required
zone_names list[str]

The zone systems to fill, e.g. ["TAZ1454"] fills work_TAZ1454.

required

Returns:

Type Description
pl.DataFrame

persons with the workplace columns filled where the rule applies.