Catalog PyPI
PACKAGE EXPLORERView in registry

activitymodel

PyPI

Occupant activity calendars from the French time-use survey: diary library, census matching, annual calendars

Versions collected1
Direct dependencies11From release 0.4.0
Last observed20 Oct, 18:37 UTC

README

Version 0.4.0 documentation

activitymodel

Occupant activity calendars for building energy simulation, built from the French time-use survey (INSEE Enquête Emploi du temps 2009-2010, PROGEDO-ADISP doi:10.13144/lil-0695).

activitymodel is a pure library: it never resolves a data path at import time and never fetches data. It is used by three packages at three moments:

momentwho imports itwhat it does
dataset build (Snakemake, maintainers)buildingdata pipelineactivitymodel.pipeline.build_library turns the ADISP delivery into a diary library (four parquet tables) that buildingdata uploads to GCS
census dataset buildbuildingdata pipeline / buildingmodelharmonise_census_individuals puts INSEE RP indcvi individuals in the same vocabulary the library was built with
simulationbuilding_eloadassign_clusters + generate_calendar turn the occupants of a district into a year of 10-minute activity codes per occupant

It replaces the two prototypes activity_clustering and activity-occupant-association; doc/design.md records what was wrong with them and why each part looks the way it does now.

Quick start

import polars as pl
import activitymodel as am

# 1. (pipeline) build the library from the survey files, once
from activitymodel.pipeline import LibraryBuildOptions, build_library
library = build_library("/data/edt2010", LibraryBuildOptions())
library.write("/data/buildingdata_pipeline/processed/activity_library")

# 2. (anywhere) load it back - buildingdata will serve the four tables
library = am.DiaryLibrary.read("/data/buildingdata_pipeline/processed/activity_library")

# 3. (simulation) harmonise census occupants and generate a year
occupants = am.harmonise_census_individuals(pl.read_parquet("indcvi_slice.parquet"))
occupants = occupants.with_row_index("occupant_id")
calendar = am.generate_calendar(library, occupants, year=2024, seed=42)

calendar.day_index.shape        # (n_occupants, 366)  int32 pointers into the day pool
codes = calendar.codes(0, 500)  # (500, 52704) uint8, detailed activities, Europe/Paris clock
long = calendar.to_long(0, 500) # occupant-major polars frame with an Enum activity column
python -m activitymodel.pipeline /data/edt2010 out/ --weekday 16 --saturday 10 --sunday 10

What is in the box

activitymodel/
  taxonomy.py      the 24 detailed activities, their ACTPR codes, the coarser levels
                   (presence = building_eload's, macro, mid)
  vocabulary.py    shared socio-demographic categories, age bands, matching ladder
  harmonise.py     survey individuals / census individuals -> shared vocabulary
  survey/          read the ADISP files, code the diaries (location and day-kind aware)
  clustering.py    one-hot + PCA + Ward (or weighted k-means), k-selection curves
  library.py       DiaryLibrary: the published dataset, its schema and validation
  matching.py      occupants -> (cluster_weekday, cluster_saturday, cluster_sunday)
  calendar.py      day sampling, French public holidays, AnnualCalendar
  diagnostics/     activity profiles, matrix distances, association scores,
                   hold-out validation of the matching against the uniform pool
  pipeline.py      build_library() and the command line
  tests/           synthetic fixtures; `-m integration` runs on the real files
doc/
  design.md            gap analysis of the prototypes and the decisions taken
  dataset_contract.md  the four tables, their columns, dtypes and invariants
  integration.md       what changes in buildingdata, buildingmodel,
                       buildingcalibration and building_eload, in order
  integration/         reference snippets for those changes

Measured on the real data (Paris, RP 2021, library 16/10/10 clusters)

stepresult
library build (26,056 diaries, Ward on 50 components)29 s wall
assign_clusters on 663,781 occupants1.3 s; 95.3 % (weighted) matched at the finest level
generate_calendar for 20,105 occupants, 20241.6 s, 28 MiB of day_index
codes() for 500 occupant-years25 MiB, 0.01 s
total-variation distance, matched Paris weekday profile vs national weighted survey0.048

Install

uv venv --python 3.12 .venv
uv pip install -e ".[dev,survey,fast]"
.venv/bin/python -m pytest -q

Extras: survey (pandas, to read the Stata delivery), fast (fastcluster), analysis (scikit-learn, matplotlib), dev.

Licence and data

Code: MIT. The survey is available on request from PROGEDO-ADISP and is not redistributable; the diary library holds no survey row (days are detached from people, people are aggregated into cells of at least five respondents). See doc/dataset_contract.md.

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.4.014 Oct 202611

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 18:37 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:b24a03b17e3f204ea4d154249cdb4366d16df0230695ebdb7ffa3a977ad65d78